So.

Is it as fun as it used to be?

How To Destroy Page Rendering Performance Using Just Javascript and CSS

So. Did you know that a severe impact on browser rendering time can be caused by CSS and javascript not playing nicely together? Rendering on different browsers varies by a factor of about 20 times (or whatever factor you want). I sure didn’t know.

And I have a “solution.”

So what is the situation? Consider an actual page from a webapp I’m developing. In FireFox the page loads and renders in something around 0.6 seconds. Safari loads and renders the same page in 12 seconds. This is not a contrived example.

What’s involved on the page? It displays summary information about all of the users of the webapp. The test data has 119 users. It uses [Blueprint](http://www.blueprintcss.org/) and the jQuery plugin [ListNav](http://www.ihwy.com/labs/jquery-listnav-plugin.aspx). I recommend them both, very nice. [ListNav](http://www.ihwy.com/labs/jquery-listnav-plugin.aspx) (check out the [demo pages](http://www.ihwy.com/labs/Demos/Current/jquery-listnav-plugin.aspx)) allows for easy navigation through a long list. [Blueprint](http://www.blueprintcss.org/) is a CSS framework for laying out a page using a grid (check it out, it has [demos](http://www.blueprintcss.org/tests/parts/sample.html) too), handles typography, and generally helps you make a page look decent. Blueprint works with <div>s, and ListNav wraps them up in <ul>s. Each user is represented by five <div>s within a <ul>.

On Safari, by changing the number of <div>s for each user I get:

user < div>s render time
1 0.5
2 2
3 4.25
4 7.5
5 12
6 18
8 32

To cut it short, if I remove the link tag to the Blueprint screen.css file in the header, the page renders almost instantly, even with 8 divs — but it looks like crap. There are a lot of things that are not the problem (I was “busy”, let’s say), and I don’t really want to go into it.

A few moments of thinking… what if I delay the application of the BlueprintCSS file? A little googling and I found some code in a JavaScript Kit tutorial: [Dynamically loading an external JavaScript or CSS file](http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml), which I simplified to:

function loadcssfile(filename){
  // thanks to http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
  var fileref=document.createElement("link");
  fileref.setAttribute("rel", "stylesheet");
  fileref.setAttribute("type", "text/css");
  fileref.setAttribute("href", filename);
  document.getElementsByTagName("head")[0].appendChild(fileref);
}

$(document).ready(function() { var navOpts = { initLetter: 'a' };
                               $('#user-list').listnav(navOpts);

                               loadcssfile("blueprint/screen.css") // use a real URL here
                             });

This is (obviously) in the jQuery document ready function.

And it worked! In Safari. Not so well in FireFox. Sigh. In FireFox, this caused a rendering effect: the unstyled content would flash on the screen before being being styled. So, back to the webapp, and check the user agent, and only do this trick for Safari. Well, hold on. It is actually any AppleWebKit based user agent — OmniWeb screws up too. There’s probably others. Anyway, about 0.3s in Safari, obviously no change in FireFox, and I’m happy enough for now.

It all came down to a single link element in the page’s header.

About these ads

Written by hutch

December 30, 2008 at 1:24 pm

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: