Eliminating redisplay flashes in JavaScript

The Holy Grail in creating dynamic HTML is to have a page that works perfectly even when JavaScript is disabled. You want your page to be beautiful and dynamic, but you also want it to be accessible, search-engine optimized, and printable.

To make this happen you start with plain, semantic HTML, then you add a JavaScript layer to rework the page into something better:

JavaScript vs. No JavaScript

One problem with this technique is that your JavaScript must run after the HTML has been set up and rendered on the page, so a user with a slow connection might see something like this using my JavaScript tabbifier:

Animated simulation of HTML rendered then re-rendering using JavaScript

This is not too pretty, so obviously we want to make it stop.

Your first thought might be “I’ll just add a style to the content to make it hidden (CSS display:none), then my JavaScript will run and reveal it!” But that puts a big crack in our Holy Grail, because if you use CSS to hide the content, it will not be visible to users who do not have JavaScript.

Here’s the method I used:

  1. Add a class javascript-hide-me to the content you need to hide, but do not define that class in your CSS.
  2. Before the content, use JavaScript to define the CSS class. The easiest way to do this is by using document.write in the head section of the page, but you will have to directly modify the DOM if you are serving XHTML pages that use MIME type application/xhtml+xml.
  3. After the content has been transformed, use JavaScript to remove the CSS class and reveal the content.

Here are two examples, one that exhibits the flashing problem, and another that fixes it using the technique described above. Note that in order to see the flashing problem, you need a slow internet connection: I recommend throttling your connection using the excellent Charles Web Debugging Proxy.

Updates 2006-03-09

Welcome, Ajaxians!

Bobby describes an alternate technique in case you are serving XHTML pages that use MIME type application/xhtml+xml.

Steve Clay makes a valid point that we should check for DOM compatibility before writing the styles on the page.

10 Responses to “Eliminating redisplay flashes in JavaScript”

  1. wilfred nas says:

    great idea, I will be trying this first thing tomorrow. Thanks patrick

  2. Rob says:

    i must say i really like your commetn setup. nice work. peace!

  3. pat says:

    Thanks, it was quickly put together, but pretty easy using my tabber software. It has a few drawbacks, because there is a named anchor in the “Leave a Comment” tab, but the tab is not displayed when you jump to the anchor. I’ll be looking into a possible solution but my gut tells me there is no way to handle that case perfectly.

  4. Warren Noronha says:

    Cool!

  5. [...] Patrick Fitzgerald has written up his technique for eliminating redisplay flashes in JavaScript. [...]

  6. Paul says:

    This is pretty cool. I am investigatinng ways of minimising scrolling on xhtml_mp devices. Although javascript is not of course supported by phone browsers, this tabbed metaphor is a really good way to compress vertical space. Thanks for the inspiration

  7. [...] And third, when I view the DOMinclude demo (click “Phillip Pullman: The Amber Spyglass”), I get some brief flickering as the iframe is repositioned. Perhaps this issue could be resolved using Pat Fitzgerald’s technique for eliminating redisplay flashes. [...]

  8. [...] Since I wrote that article I came up with a technique that solved the problem (as well as the “flicker” problem that occurs with some fixes). This past week I came up with what I believe is an even better solution which I plan on using in upcoming projects. I’ll share both with you here in this post. [...]

  9. Regarding the whitespace while the tabber is loading, how about adding a “Loading” message or image so that on tab ui with a lot of images or text it won’t look like the page has frozen.

    I really enjoy using the script and i must say – great work!

  10. I don’t understand this at all, and i’ll pay someone a couple bucks if they set this up for me. contact me through my website, the sooner the better

Leave a Reply