James
James

Reputation: 1085

IE, Javascript and Reflow

I have a javascript function that changes the css display ('block', 'none') of a large number of dom nodes (>5000). I am trying to make this as fast as possible.

Will IE interrupt javascript to reflow and paint the screen, or will it wait until the javascript engine returns control to the browser? I want to avoid any extra work from the browser until all nodes have had their display set.

I noticed in JQuery's show() method, DOM operations are put in a tight loop with the comment

// Set the display of the elements in a second loop
// to avoid the constant reflow

(http://code.google.com/p/jqueryjs/source/browse/trunk/jquery/src/fx.js line 51)

Thanks,

James

Upvotes: 2

Views: 2475

Answers (3)

edeverett
edeverett

Reputation: 8218

The browsers will reflow the page as the JS changes each element. As you are suggesting, it is best to keep the changing of the display until the end. This will also feel smoother and faster (even if it isn't really) to the user.

I would:

  1. Clone a node that wraps the nodes that you want to process.
  2. Do the processing on the cloned nodes children.
  3. Replace the original node with the clone.

If the processing takes a long time (more than 0.5 of a second) consider setting something on the display to let the user know that something is happening. Slowly fading out the original content to a minimum of a about 50% opacity is a simple way.

Upvotes: 0

Guffa
Guffa

Reputation: 700800

Use CSS to show and hide the elements instead, by changing the class name of a parent element. Some tests I did a while back showed that it's about ten times faster than setting the display property on each element. As you are only changing a single attribute, it only reflows once.

Example:

<style>
.State1 .InitiallyHidden { display: none; }
.State2 .InitiallyShown { display: none; }
</style>

<script>
function flip() {
   var o = document.getElementById('Parent');
   o.className = o.className = 'State1' ? 'State2' : 'State1';
}
</script>

<input type="button" value="flip" onclick="flip();" />

<div id="Parent" class="State1">
   <div class="InitiallyHidden">One</div>
   <div class="InitiallyShown">Two</div>
   <div class="InitiallyHidden">Three</div>
   <div class="InitiallyShown">Four</div>
</div>

Upvotes: 2

Allen Rice
Allen Rice

Reputation: 19446

If you hid a common parent, and then hid the elements, and then showed the parent, that should keep it from repainting unnecesarrily.

Upvotes: 0

Related Questions