5

When something is appended to the DOM in memory, does that cause a browser reflow? Or is it only when the pixels on the screen are told to change that the reflow happens? For example:

Case 1: Img elements appended to the DOM one at a time

var parentDiv = $('#imgHolder');
var imgArray = []; // Array of img paths populated in another function

$.each(imgArray, function()
{
    parentDiv.append(createImgEle(this)); // createImgEle() // returns an <img> with the right src
}

Case 2: Img elements are put in a separate array and then appended to the DOM

var parentDiv = $('#imgHolder');
var imgArray = []; // Array of img paths populated in another function
var tempArray = []; // Holds the img elements until its fully populated

$.each(imgArray, function()
{
    tempArray.push(createImgEle(this));
}
parentDiv.append(tempArray);

Case 3: Either case 1 or 2 but by default, parentDiv is set to display:none; and made visible after the each loop is done.

Basically, what I want to know is, does the browser only start to reflow when the pixels of the screen are told to change?

Btw, the code is only for example purposes and not in production so don't slam me for any logic errors. Thank you for any advice.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Matt Whitehead
  • 1,743
  • 3
  • 19
  • 34
  • In case 1, you'll get a redraw per append, and in case 2 you'll get one redraw. Case 3 i'm not sure tbh. I'd go with case 2 – Kevin B Feb 08 '13 at 22:10
  • 2
    I wonder what cross-browser differences there will be with this though. Does IE handle it differently than say, Chrome or Firefox? – Kevin B Feb 08 '13 at 22:11
  • The general best practice (based on numerous answers here and on the jQuery forums, and my own experience) is to only perform one append to the DOM. Whether that means appending an array all at once, or creating a DOM Fragment and appending the contents of the DOM Fragment doesn't matter. Either way, you're only touching the DOM once. – Kevin B Feb 08 '13 at 22:18
  • @KevinB Yeah, that's what I've found as well. But I'm just wondering if the reflow occurs *only* when the pixels are told to change. – Matt Whitehead Feb 08 '13 at 22:21
  • 1
    Well, what causes the reflow? the pixel changing, or the attribute/style/dom structure changing. I would expect the reflow to be triggered by the changes made to the DOM, and potentially optimized to not cause a reflow on hidden elements( not tested, and may be browser-dependant) I'm not sure how to test this. – Kevin B Feb 08 '13 at 22:23
  • @KevinB Agreed. It'd be nice to know how this is handled in the major browsers. I'll have to do some more sleuthing around on Google and see if I can find anything else. – Matt Whitehead Feb 08 '13 at 22:27
  • Here's a good resource: https://developers.google.com/speed/articles/reflow – Kevin B Feb 08 '13 at 22:29

1 Answers1

3

Basically, what I want to know is, does the browser only start to reflow when the pixels of the screen are told to change?

No, the browser reflows when the DOM changes. After that, it will repaint (tell the pixels on the screen to change).

For the details, have a look at this dev.opera.com article and the question When does reflow happen in a DOM environment?.

In short: There is of course optimisation for subsequent DOM changes, for example if you insert an array of elements in a loop. I would not expect your cases 1 and 2 to differ noticeable.

Only if you are doing really heavy DOM changes, you might need case #3. This makes reflows, should they happen during the insert loop, stop when encountering the hidden elements so they are basically prevented. However, the two display changes before and after the loop can lead to flickering in some browsers.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375