Showing posts with label class. Show all posts
Showing posts with label class. Show all posts

Friday, 17 August 2007

Firefox 2.0.0.6 vs Opera 9.20

This post is not just to let you know what browsers I'm using at the moment.
It's rather about this speed problem a colleague of mine and I are having for a web application.

Just to make it simple, there are two divs, each contain a huge table, each with around 100 rows of 20 columns each, in each cell there is either some text, a checkbox or a select tag with around 5 options. Just to sum things up, there are like 800 checkboxes and 800 selects. They are loaded by pulling data from the server through a HttpRequest object.

We were expecting loading to take a long time and it really does :-)
What is really surprising is what happens when they're both loaded and their classNames are changed, one gets a class name that has among others "display: none" to hide it and the other gets "currentDiv" class name which sets a few properties.

I'm really surprised about how ling time it takes Firefox 2 to do this operation. I checked with FireBug exactly what part of the code takes the most to run and this is it:

  myDiv.className = "currentDiv";

This is where it spends around 10 seconds.

I thought instead of changing the class name, to try and change the style.display property, but there was no visible difference. Here's a nice test on this subject.

Just for tha hell of it, I also took down any other CSS properties from the "currentDiv" class and especially these kind of lines:

  div.currentDiv table td.commentTd{ ... }

I thought maybe the rendering engine has to go through all cells of the table in this specific div and change the visual attributes. Well, again, no improvement.

I was curious what had Opera to say about this matter and I tested the same code on Opera 9.20. Result: under 2 seconds including loading the div. Absolutely surprising.

I'm not giving up on Firefox, yet, I still love it :-) But I'm looking forward to Firefox 3 with its new and improved JavaScript engine ;-)

Monday, 16 July 2007

Loading dependencies in JavaScript

Isn't it nice to work modularized, even in JavaScript?
I like putting all my classes in their own files and all the little functions that don't belog to any class in a file called toolbox.js

That's pretty neat and organized, but when it comes to inserting all the necessary js files into your webpage, it's a pain, isn't it?

Well, not for me. I add the toolbox.js to every webpage that uses JavaScript and then the most important js file for that particular page.

Here's an example; I have a webpage that needs to use the EntryModule class. But this class needs a few more classes that are stored in other files, the TableEntryClass, the TextEntryClass and ColourObjectClass. All I need to do is to call this function:

loadDependencies(Array('js/ColourObjectClass.js', 'js/TableEntryClass.js', 'js/TextEntryClass.js'));

This function takes either a string or an array of strings that specify the js files to add to the same webpage that loaded EntryModuleClass.js

Here's the code, use it wise:

function loadDependencies(dependency)
{
  var head = document.getElementsByTagName('head')[0];
   var scripts = head.getElementsByTagName('script');
  var i, j, newjs;
  if(typeof dependency == 'string')
  {
    //search if it's loaded already
    for(i=0; i < scripts.length; ++i)
      if(scripts[i].src.toLowerCase() == dependency.toLowerCase())
        return;
    //if not, load it
    newjs = document.createElement('script');
    newjs.type = 'text/javascript';
    newjs.src = dependency;
    head.appendChild(newjs);
  }
  if(typeof dependency == 'object')//it must be an array
  {
     //search if it's loaded already
     for(i=0; i < dependency.length; ++i)
     {
       for(j=0; j < scripts.length; ++j)
         if(scripts[j].src.toLowerCase() == dependency[i].toLowerCase())
           return;
       //if not, load it
       newjs = document.createElement('script');
       newjs.type = 'text/javascript';
       newjs.src = dependency[i];
       head.appendChild(newjs);
     }
   }
}

I hope you notice the care I took with declaring the variables at the begining of the function and also getting the head tag and the script tags at the begining to optimize the number of searches...