IE+JavaScript Performance Recommendations Part 2: JavaScript Code Inefficiencies


Hello again, this is Peter Gurevich, Performance PM for IE. We have gotten a lot of good feedback from our first post on IE + JavaScript Performance Recommendations so I am eager to hear what you think of our second installment. This is the first of two posts concerning inefficiencies in Javascript code itself.

JScript Code Inefficiencies – Chapter One

There are plenty of ways to use JScript (and other Javascript engines) inefficiently since the interpreter performs almost zero optimizations when interpreting code. Most of the recommendations in the previous post are where a rather large inefficiency shows itself in many different forms. Here we’ll be concentrating on specific inefficiencies related to string manipulation and dynamic code evaluation.

Optimize String Manipulations by Avoiding Intermediate Results

Most JScript code used for manipulating the IE DOM requires some sort of string manipulation. While most of the performance that is lost in string manipulation is due to name resolution and binding of the properties on objects you are working with, much of it can also be explained away by making the wrong assumptions about how strings are handled.

The first piece of erroneous code comes in using the standard string concatenation operator + when working with strings. Strings are stored in Jscript on the heap and a pointer to them is located within the garbage collector. Each intermediate string manipulation results in another temporary allocation of memory. Most languages have some construct for intermediate string results, such as a StringBuilder in .NET or a buffered string class in C++. For the JScript language buffered strings are created using the Array.join function. The following sample creates a larger string by concatenating together many smaller strings.

var smallerStrings = new Array();
// Fill the array with smaller strings
var myRatherLargeString = “”;
var length = smallerStrings.length;
for(var index = 0; index<length; index++)
{
    myRatherLargeString += smallerStrings[index];
}

Performance articles often note this type of construct is slow. Looks can be deceiving here since the extra overhead of obtaining the smaller, intermediate strings is making this slow. The above code sample would work much better when rewritten using Array.Join.

var myRatherLargeString = smallerStrings.join(‘’);

Not only is the code simpler, but it is also much faster for this case. When the number of values being concatenated is small enough the concatenation operator still wins. The cross-over point is not entirely deterministic, but exists somewhere in the neighborhood of 7-13 values. For larger strings the count may be much smaller. You’ll have to do performance testing when you choose this approach and make sure it fits your algorithm. The following code sample is optimized to point out the cut-off point.

<script>
var markupBuilder = new Array();
markupBuilder.push(“<div id=””);
markupBuilder.push(“sampleID”);
markupBuilder.push(“”>”);
markupBuilder.push(“sampleText”);
markupBuilder.push(“</div>”);
var markupBuilder2 = new Array();
markupBuilder2.push(“<div id=””);      // 0
markupBuilder2.push(“sampleID”);        // 1
markupBuilder2.push(“”>”);             // 2
markupBuilder2.push(“sampleText”);      // 3
markupBuilder2.push(“</div>”);          // 4
markupBuilder2.push(“<div id=””);      // 5
markupBuilder2.push(“sampleID”);        // 6
markupBuilder2.push(“”>”);             // 7
markupBuilder2.push(“sampleText”);      // 8
markupBuilder2.push(“</div>”);          // 9
markupBuilder2.push(“<div id=””);      // 10
markupBuilder2.push(“sampleID”);        // 11
markupBuilder2.push(“”>”);             // 12
markupBuilder2.push(“sampleText”);      // 13
markupBuilder2.push(“</div>”);          // 14
markupBuilder2.push(“<div id=””);      // 15
markupBuilder2.push(“sampleID”);        // 16
markupBuilder2.push(“”>”);             // 17
markupBuilder2.push(“sampleText”);      // 18
markupBuilder2.push(“</div>”);          // 19
function buildDivJoin(id, innerText, short)

    if ( short ) 
   {
        markupBuilder[1] = id;
        markupBuilder[3] = innerText;
        return markupBuilder.join(“”); 
   }
     else 
   {
        markupBuilder2[1] = id;
        markupBuilder2[3] = innerText;
        markupBuilder2[6] = id;
        markupBuilder2[8] = innerText; 
        markupBuilder2[11] = id;
        markupBuilder2[13] = innerText;
        markupBuilder2[16] = innerText;
        markupBuilder2[18] = innerText; 
        return markupBuilder2.join(“”); 
   }
}
function buildDivConcat(id, innerText, short)

    if ( short ) 
   {
        return “<div id=”” + id + “”>” + innerText + “</div>”; 
    }
    else 
    { 
        return “<div id=”” + id + “”>” + innerText + “</div>” +
            “<div id=”” + id + “”>” + innerText + “</div>” +
            “<div id=”” + id + “”>” + innerText + “</div>” +
            “<div id=”” + id + “”>” + innerText + “</div>”; 
    }
}
function perfTestDivs()
{
    var start = (new Date()).getTime();
    for(var i = 0; i < 25000; i++) { buildDivJoin(“foo”, “innerText”, true); } 
    var end = (new Date()).getTime();
    output.innerHTML += “Join short ” + (end – start) + “<br>”; 
    start = (new Date()).getTime();
    for(var i = 0; i < 25000; i++) { buildDivConcat(“foo”, “innerText”, true); }
    end = (new Date()).getTime();
    output.innerHTML += “Concat short ” + (end – start) + “<br>”;
    var start = (new Date()).getTime();
    for(var i = 0; i < 10000; i++) { buildDivJoin(“foo”, “innerText”, false); }
    var end = (new Date()).getTime(); 
    output.innerHTML += “Join long ” + (end – start) + “<br>”;
    start = (new Date()).getTime();
    for(var i = 0; i < 10000; i++) { buildDivConcat(“foo”, “innerText”, false); }
    end = (new Date()).getTime(); 
    output.innerHTML += “Concat long ” + (end – start) + “<br>”;
}
function perfTest()

    output.innerHTML = “”; 
    perfTestDivs();
}
</script>
<body>
<button onclick=”perfTest()”>Performance Test</button>
<div id=”output”></div>
</body>

Even with the concatenation operator winning every now and then it isn’t always best to use it when you are unsure about the destination of your operation. As noted in the symbolic look-up section in the previous post , it can be very expensive to work on a DOM property  such as innerHTML and concatenate text a little bit at a time. Even worse, property operations are not guaranteed to round trip so operations performed bit by bit against the DOM may not be the same as performing them all at once.

<head>
<script>
function InjectMangle()
{
      var strContent = “<object>Fallback Text</object>”;
      var oDiv = document.getElementById(“injectSpot”);
      oDiv.innerHTML = strContent;
      setTimeout(“CheckInject()”, 1000);
}
function CheckInject()
{
      var oDiv = document.getElementById(“injectSpot”);
      alert(oDiv.innerHTML);
}
</script>
</head>
<body>
<button onclick=”InjectMangle();”>Perform Injection Check</button>
<div id=”injectSpot”></div>
</body>

The general wisdom here is to first create your final strings in local variables if possible and then copy them into the properties on your objects. Especially if the properties you are working with may change their values if you do your work in parts. Concatenation of large strings is done much faster if you use Array.join and you’ll also save a lot of memory that would have been used for storing intermediate string results. Finally, never use the concatenation operator if you are working with properties on objects within IE or any other ActiveX control. If at all possible it is best to avoid the extra name look-ups and potentially expensive property accesses.

Running Code Using the ‘eval’ Statement is Expensive

The title explains it all. The eval statement in JScript is both expensive in terms of performance and prone to error if the site is generating dynamically the script to be run. If you can remove it from your application you should do so. You’ll need to replace it with functional equivalents where the dynamically evaluated code can be simulated by changing the input parameters. This general wisdom not only leads to faster code in most cases but can also make your program more reliable and easy to understand. If arbitrary code is executing on the client machine it becomes hard to determine how it failed.

For those interested in the “why”, execution of an arbitrary string of script involves the construction of a new script runtime, copying the context of the currently executing script, manipulation of the runtime stack, and a bit of other work. This isn’t much different from running other code, but isn’t nearly as fast as writing the inline branching code to handle all of the possibilities of the dynamically generated code. There are obviously good uses for the eval statement, just examine your project thoroughly before taking a dependency on it.

Requirements of Eval for JSON Expressions

Now that we’ve warned against eval let’s talk about when it can be useful! JSON is becoming more and more popular as a data protocol written on top of the JScript language. Along with any protocol it has concerns for security and tampering and therein lies a problem. Security means validating large chunks of data for potentially malicious code and of course all of this takes time. The purpose behind JSON was to quickly and easily transfer data into in memory usable structures, something faster than parsing, and in some cases it can actually be slower so you have to be careful. Those cases where it tends to be slower are when your data strings begin to get extremely large. The evaluation time of the security regular expression and creating a temporary copy of the script to be evaluated (both properties of the current standard JSON parser) start to add up. When your JSON requests start generating 200K character strings you might want to think about your process.

What can you do here? Well, if you use JSON follow the standards and don’t try to change the published protocols since that could negatively affect the performance in one or more browsers that you don’t test against. Make sure you put constraints on your data sizes so that the JSON protocol evaluation doesn’t take too long and hang the browser. Remember, while those structures are being built, nothing else can be done.

Switch Blocks are Linear Evaluation Tables

The switch statement doesn’t know that the values are sorted in some way that lends itself to effectively a nested if structure – most languages will heavily optimize this, as Justin talked about on his blog a couple of years ago, but JavaScript doesn’t. If you have a large switch it is best to break this down into a series of nested if statement comparisons, an array where you can perform a binary search, or my personal favorite a sparse array (hash-table). The following code sample translates id values to their string identifiers. This is a common feature to reduce the amount of data transferred between the client and the server.

<script>
function mapIdToString(id)

    switch(id) 
    { 
        case 0: 
            return “User Record”; 
        case 1: 
            return “Management Record”; 
        case 2: 
            return “Product Record”; 
        case 3: 
            return “Sale Record”; 
        default: 
            return “Product Identifier ” + id; 
    }
}
</script>

As you can see we have a couple of common cases and a default clause that maps anything left over. We might be calculating a few thousand of these over and over again and running through the same switch. As we add more known values the number of comparisons increases linearly. At some point the switch becomes increasingly slower than writing the expanded set of if statements with range checks (a static binary search of the data). In fact, a simple optimization depending on the data, might just be to add a check for any value that would end up in the default clause and prevent doing all of the extra known value checks just to create a new product identifier.

For larger data sets you can use an array to map id’s to names based on indexing into the array. If the id is a sparse value (not incrementing) then you might need to sort the array and perform a binary search for the id of interest. This requires maintaining some structure that can hold both the id and the string value and is outside of the scope of the article, implementing the sort algorithm for this structure, and creating a binary search routine in JScript. While we could add that type of information here the next option is much easier to implement and provides nearly all of the same benefits.

JScript maintains an associative array (also known as a hash-table) that can be used for any mapping operations. A simple HTML tag parser might take advantage of this by inserting functions for handling a particular tag type into a hash-table indexed by tag name. This would be significantly more robust and surprisingly faster than the equivalent switch statement. As a technical note on the script itself, we’ve placed a try…catch block to catch malformed input. Where this block should reside and what happens on error is up to the algorithm. The normal switch statement is already robust to malformed input.

<script>
function Parser_Div(tokenizer, perf)

      if ( !perf ) 
            output.innerHTML += “Parsing a DIV<br>”;
}
function Parser_Span(tokenizer, perf)

      if ( !perf ) 
            output.innerHTML += “Parsing a SPAN<br>”;
}
function Parser_Para(tokenizer, perf)

      if ( !perf ) 
            output.innerHTML += “Parsing a P<br>”;
}
var o = new Array();
o[“DIV”] = Parser_Div;
o[“SPAN”] = Parser_Span;
o[“P”] = Parser_Para;
function Parser(perf)

      if ( !perf ) 
            output.innerHTML = “”; // Clear our output 
      var tokenizer = source.innerText.split(‘ ‘); 
      for(var i = 0; i < tokenizer.length; i++) 
      { 
            o[tokenizer[i]](tokenizer, perf); 
      }
}
function SwitchParser(perf)

      var tokenizer = source.innerText.split(‘ ‘); 
      for(var i = 0; i < tokenizer.length; i++) 
      { 
            switch(tokenizer[i]) 
            { 
                  case “DIV”: Parser_Div(tokenizer, perf); 
                  case “SPAN”: Parser_Span(tokenizer, perf); 
                  case “P”: Parser_Para(tokenizer, perf); 
            } 
      }
}
function Perf()

      output.innerHTML = “”; 
      var start = (new Date()).getTime(); 
      for(var i = 0; i < 5000; i++) { Parser(true); } 
      var end = (new Date()).getTime(); 
      output.innerHTML += “Hash Parser ” + (end – start) + “<br>”; 
      start = (new Date()).getTime(); 
      for(var i = 0; i < 5000; i++) { SwitchParser(true); } 
      end = (new Date()).getTime(); 
      output.innerHTML += “Switch Parser ” + (end – start) + “<br>”; 
      start = (new Date()).getTime(); 
      for(var i = 0; i < 5000; i++) { Parser(true); } 
      end = (new Date()).getTime(); 
      output.innerHTML += “Hash Parser ” + (end – start) + “<br>”; 
      start = (new Date()).getTime();       for(var i = 0; i < 5000; i++) { SwitchParser(true); } 
      end = (new Date()).getTime(); 
      output.innerHTML += “Switch Parser ” + (end – start) + “<br>”;
}
</script>
<button onclick=”Parser(false);”>Parse!</button>
<button onclick=”Perf();”>Perf!</button>
<div id=”source”>DIV SPAN P DIV SPAN P DIV SPAN P DIV SPAN P DIV SPAN P DIV SPAN P DIV SPAN P DIV SPAN P DIV SPAN P DIV SPAN P DIV SPAN P DIV SPAN P</div>
<div id=”output”></div>

For such a small number the switch is likely faster, as we start growing the number of tags handled the hash-table will eventually win. Depending on the format of your data make use of the appropriate constructs and avoid the switch when a large number of comparisons are going to be needed.

That’s all for Part 2.

Thanks,

Peter Gurevich
Program Manager

Justin Rogers
Software Development Engineer

Comments (77)

  1. Tom says:

    Now that’s a long blog post 😉

  2. Robin says:

    I’m confused. Are we talking about Javascript or JScript here:

    <i>most languages will heavily optimize this, as Justin talked about on his blog a couple of years ago, but JavaScript doesn’t</i>

    Surely optimisation is done in the interpreter, not the language?

  3. devil's advocate says:

    why do I get the suspicion that this is a result of trying to speed up all that AJAX crap thats showing up these days

  4. Maian says:

    Good tips, but a couple nitpicks:

    1) You should point out the main misuses of eval and how they can be avoided. For ex:

    eval("document.forms." + name + ".value=’foo’")

    should be

    document.forms[name].value = ‘foo’

    Actually that’s a bad example, since document.forms isn’t really a JS object; it’s a native object. But in general:

    eval("obj."+prop) => obj[prop]

    2) JavaScript’s associative array isn’t Array; it’s Object. Array is just an Object with a magical length property and array methods.

  5. paul says:

    can you please fix your sample code, to include proper tags! if you plan for others to learn from this code, it should be a "good" example.

    e.g. all the "<br>" tags should be "<br/>".

    Second, can you use a different style text (cough, cough) FIXED FONT for the samples, and make it a different color than the default links in this Blog!

    You’ll want to add [type="text/javascript"] to your script tags too.  It is the default, yes, but again, you’re trying to lead by example.

    ps Thanks for not using a single UPPERCASE tag! This actually makes your code sample look much more professional.

    Paul

  6. joel says:

    I don’t remember .innerHTML being part of the DOM spec? or even supported by all browsers?

    Web Developers don’t write browser specific code, remember!?*

    *Well, ok we often have to, to get around quirks, but I would have altered the example to be more x-browser/DOM compliant.

  7. steve_web says:

    I love how your InjectMangle function, so very clearly illustrates the button bug that we’ve be complaining about in the last thread.

    so, any chance of some ETA’s on these fixes?  ETA’s on the Bug tracking system?

  8. joel says:

    ah, before I get reamed… I meant .innerText, not .innerHTML which every browser seems to support now.

  9. Tino Zijdel says:

    I’m repeating myself: beware of browser-specific implementations

    The fact that string-concatenations are slow in JScript is because of a poor implementation (not keeping a pointer to the end of the string). Only in JScript is the Array.join()-approach faster, in other javascript-capable browsers concatenations using the + operator are much faster.

    Opera blogged recently ( http://dev.opera.com/articles/view/efficient-javascript/ ) that it is even better to do:

    a = a + ‘something’;

    a = a + ‘something more’;

    than to do:

    a = a + ‘something’ + ‘something more’;

    which is true, except in JScript…

    As for the ‘necessity’ of eval for JSON I also disagree; it’s quite easy to create a parser for JSON in javascript that doesn’t rely on eval()

    For the last part, the switch block, I will do some testing. It might just be that this is implementation-specific as well.

  10. Jeff L says:

    Just another nitpick – your code sample above uses

    setTimeout("CheckInject()", 1000);

    wouldn’t it be more efficient to just do

    setTimeout(CheckInject,1000);

    http://dev.opera.com/articles/view/efficient-javascript/?page=2#timeouts

  11. Tino Zijdel says:

    To nitpick some more: please don’t write examples that rely on propriety extensions (innerHTML) or IE-only propriety extensions (innerText and elements with name/id being available in the global namespace*).

    Also please use valid markup, which means adding a type attribute to your script starttags and properly escaping any endtags within script. You are posting on a high-profile blog so your examples should at least pass a simple validity-check.

    * document.all should have been deprecated with IE5 and should have been extinguished in IE7.

  12. Scott says:

    I read the article and understood the concepts, but had a tough time following most of the examples. Having read the comments, it sounds like its for the best.

    I’ve read in many places that I should never use X or Y, but nobody seems to be saying the correct way to be doing things. Hopefully you JavaScript masters out there can appreciate that I’m a little wary of blindly going to web sites and trying to learn the right way to do things for fear of actually learning the wrong way to do things. Can anybody recommend any good ones to me? I’m already planning to some day buy the two recent books, one by Jeremy Keith and the other by Peter Paul Koch, in case you were going to recommend those to me.

  13. Maian says:

    Actually, ‘x’ + ‘y’ would resolve to ‘xy’ during compile-time in some JavaScript engines, including either Spidermonkey (Mozilla’s) or Rhino (Java equivalent) – I forgot. By compile-time, I mean the stage where the engine’s parser builds up the parse tree before interpreting it (which would be run-time). This only works for adjacent string literals though, not vars containing strings.

  14. I’ll try to follow up with all of the comments, but the general gut check is that people don’t like my style. Some people pointed out the lack of XHTML (yep, sorry IE doesn’t support it), we made the mistake of referencing JavaScript in a couple of places which should probably be JScript, as we are clearly talking about our own implementation here and how to speed things up when using IE.

    I’ve also noticed that some of the other browsers have their own performance optimizations. For instance, the setTimeout call above, noted as not optimal, is treated in IE in such a way as to be almost optimal (though we do generate one extra anonymous function that isn’t needed).

    The most interesting comment so far is on JSON though. I think there probably are more efficient parsers than the use of eval. In fact, I would hope that someone would provide one for public consumption. If you have something go on over to http://www.json.org and convince them to pick it up!

    If the content of the post here tends to be too much about what not to do, the intent of the code samples is to provide a quick basic work-around for use with IE. These tips if you will are based on common scenarios that we’ve discovered can be improved and acted upon by the web developer now. These are not and will not be replacements for actual improvements in IE’s implementation as we release new versions.

  15. Wraith Daquell says:

    Sour, sour, sour. I’ve come to a conclusion about commenting web developers which I won’t share here.

    I thought the optimizations, particularly the string manipulations, were quite good. I’ll remember to use them. For those that look down at various aspects of JScript and its implementation, remember that IE is faster in other ways than Firefox or Opera. Even Superman had issues…

  16. If you’re going to assign arbitrary properties to an object, as in this example:

    var o = new Array();

    o["DIV"] = Parser_Div;

    o["SPAN"] = Parser_Span;

    o["P"] = Parser_Para;

    Why not instantiate o as an object instead:

    var o = {};

    Since you’re not using o as a sequence, why do you instantiate it as an Array?

  17. Mike says:

    I would like to commend the IE team for publishing this article and developers should be aware as much as possible of these issues. As for myself I intend to write code for readability and maintainability.I use lots of switch statements for preciously this reason, I could change that and make my code slightly quicker in IE but no doubt it would have a detrimental effect in other browsers. Likewise string-concatenations I am not changing my code because of an implementation quirk in one browser. I wish all developers would do the same aim to write clear maintainable code, it is up to browser makers to optimize their iterpreters. If all developers did this the onus would fall on browser makers to sort out these problems.

  18. Array.join for string concatenations sounds like a good tip. It is only marginally less readable and I can see why this would speed things up.

    However using a hash function instead of a case statement makes the code much much less readable.  It also restricts the number of values you can have for each case and forces you to create a function for each case statement, neither of which you would allways want.

    I am sure there are occasions where the optimised code would be needed, but for most cases readability and maintainability should take precedence.

    Finally I would like to point out that "Most script code used for manipulating the IE DOM requires some sort of string manipulation" is not a good premise to start an article on. There are built in methods for manipulating the DOM which require no string manipulation at all.

  19. r says:

    You really should remove commenting from this web log. All the Mozilla morons are annoying.

  20. Dao says:

    Don’t do this:

    var markupBuilder = new Array();

    but:

    var markupBuilder = [];

    Don’t do this:

    setTimeout("CheckInject()", 1000);

    but:

    setTimeout(CheckInject, 1000);

  21. Dao says:

    > var o = new Array();

    > o["DIV"] = Parser_Div;

    > o["SPAN"] = Parser_Span;

    > o["P"] = Parser_Para;

    Man, that’s nonsense.

    What you have here isn’t an "associative array" but an array object where you add properties. But then there’s no need to use an *array* object.

    What it should look like:

    > var o = new Object;

    > o.DIV = Parser_Div;

    > o.SPAN = Parser_Span;

    > o.P = Parser_Para;

    Which can be optimized further:

    > var o = {

    >  DIV: Parser_Div,

    >  SPAN: Parser_Span,

    >  P: Parser_Para};

  22. Could you tell me if "new Function(code)" is a good replacement for eval? That could be a way to parse json without the scope latency brought by eval.

    Example:

    return eval(json_string);

    vs.

    return (new Function("return " + json_string))();

  23. Mike says:

    I agree with Dao but can he or someone else explain why using

    var markupBuilder = [];

    is better than

    var markupBuilder = new Array();

    Surely both do the same and create a new array object. I am talking about array creation here as correctly pointed out an object should have been used in the example.

  24. Tobie Langel says:

    <blockquote>You really should remove commenting from this web log. All the Mozilla morons are annoying.</blockquote>

    That was funny!

    Great article by the way, despite it being quite IE flavored.

  25. seems that You forget String.concat native method, supported by every browser, IE4 too …

    I’ve tested that

    var bigString = someString.concat(a, b, ‘c’, d, e, f, g, h, i(), j)

    … is even faster than array creation with a join solution

    var bigString = [a, b, ‘c’, …. , j].join(”)

    and both are faster than ‘plus sign’ concatenations.

    I often use String.concat starting from empy string too

    return ”.concat(what, ever, you, need)

    useful for example with CSS size (first element isn’t a string)

    return ”.concat(myInt32Size, ‘px’);

  26. Dao says:

    @Mike

    > I agree with Dao but can he or someone else explain why using var markupBuilder = []; is better than var markupBuilder = new Array();

    Because it’s faster.

  27. Dao says:

    @Sebastian Werner

    > Could you tell me if "new Function(code)" is a good replacement for eval?

    I’m pretty sure it’s as inefficient as eval.

  28. While reading several posts about JavaScript performance [ 1 ] [ 2 ] I did a simple test, too. My first

  29. TheSteve says:

    Excellent post.  I could definitely use this as a reference if I needed to do some optimizations.  I have a habit of optimizing all my code when I have the time to do it — a habit I picked up from 3D programming.

    At the same time, I hope the knowledge you have of these inefficiencies is put to good use in future IE versions.

  30. cooperpx says:

    @ Justin Rogers

    "The most interesting comment so far is on JSON though. I think there probably are more efficient parsers than the use of eval. In fact, I would hope that someone would provide one for public consumption."

    Can you please elaborate on this? How can a JavaScript JSON parser be faster than a native one? ~ or did I just misunderstand your post?

  31. Jerry Pisk says:

    I also find the fact that the article calls for standards when mentioning JSON but uses innerHTML and innerText quite amusing. Microsoft just do not get it.

    As for Scott: the correct way to add elements to an existing document once it’s parsed is through DOM (and no, innerHTML or inner Text are not part of DOM):

    function BuildDiv(id, text) {

     var div = document.createElement("div");

     div.setAttribute("id", id);

     div.appendChild(document.createTextNode(text);

     return div;

    }

    The above works even in IE since at least IE5. In the end, this is what using innerHTML will end up in, the browser will parse it and create the objects for you. I don’t understand why some people think concatenating strings is a better way to create the objects you need.

  32. Dao says:

    > How can a JavaScript JSON parser be faster than a native one?

    Because you don’t have to "construct a new script engine, copying the context of the currently executing script". I still doubt a custom parser would be faster, though.

  33. Yes, this is DOM compliant:

    > function BuildDiv(id, text) {

    >  var div = document.createElement("div");

    >  div.setAttribute("id", id);

    >  div.appendChild(document.createTextNode(text);

    >  return div;

    > }

    But this is reality compliant:

    div.innerHTML = text;

    When you start generating a large chunk of HTML and want to insert it, using DOM operations is painfully slow and is not atomic (instead of "blitzing" the new HTML into the DOM, you would be gradually updating the DOM, which may have undesirable visual effects).

    As this article is about improving performance, favoring innerHTML is the right way to go.

  34. TMaster says:

    ***OFFTOPIC***

    I’m afraid I found a bug in the IE7 feed functionality: I was (am) subscribed to http://google.blognewschannel.com/index.php/feed/, but ever since that URL started returning a HTTP 404 error code, ALL my feeds have stopped refreshing their content entirely. I now have to right click and select "Refresh All". I just updated the two 404ed feeds, and don’t know yet if they’re updating automatically again.

    What is the current suggested way to report non-critical bugs in IE7?

  35. JD on EP says:

    Lots of links: When I have so many browser windows and tabs open it’s time to harvest some… here are some links I’ve found this week that I found interesting, and you may too….

  36. @Stoyan and @Dao, regarding your comments. Have you seen this sentence from the Opera links you have posted?

    "The Function constructor is not quite as bad as eval, since using it does not affect the code surrounding the use, but it can still be quite slow."

  37. Kris Zyp says:

    I realize it is very fashionable to bash IE these days, but the topic at hand is JavaScript performance not whether people should use "non-standard" innerHTML and innerText in examples.  Anyway, it is rather naive, or at least seriously limiting to write JS on browsers and only use "standards" based functions.  Standards are great, and I certainly encourage Microsoft to follow them, but as web devs, the reality is we program to what will work for the masses, and innerHTML probably one of mostly widely implemented DOM interactions that is available, regardless of what W3C has to say about it.

    As far as JSON/evals, I believe that evals generally have a constant time component to their cost, therefore it may be possible to build a non-native JSON reader that is faster on very small snippets of JSON, but I also doubt that non-native reader could be anywhere close to as fast as an eval on all but very small JSON strings.  I thought what Justin was referring to with performance degradation with large JSON was applying Douglas Crockford’s JSON regex security checking (the JSON.parse function, that prevents functions from being included in JSON).  However, if you are getting JSON from a trusted source (and if you are making AJAX calls to your own server, you can generally trust it), then you don’t need to run the JSON regex security checker, and the slowness of the regex checks can be avoided.  I don’t see why an eval on long strings would be non-linear in cost, it is essentially the same parsing that occurs in script parsing.

    Anyway, I appreciate that Microsoft is providing information about JScript optimization.

  38. Benjamin Hawkes-Lewis says:

    Paul,

    "You’ll want to add [type=’text/javascript’] to your script tags too.  It is the default, yes, but again, you’re trying to lead by example."

    Actually, this is misleading on two counts. First, the Content-Script-Type HTTP header can be used to specify the default scripting language for the intrinsic event attributes of elements (like ONCLICK), but that header does not apply to SCRIPT elements. The TYPE attribute of the SCRIPT element is an absolute requirement and has no default value, even if a Content-Script-Type header is included. See the specification for SCRIPT:

    http://www.w3.org/TR/html4/interact/scripts.html#adef-type-SCRIPT

    Second, "text/javascript" is officially obsoleted in favour of "application/javascript". See the IANA media types registry ( http://www.iana.org/assignments/media-types/ ) and RFC 4329: Scripting Media Types ( http://www.ietf.org/rfc/rfc4329.txt ). I don’t think that media type is supported by Internet Explorer, however. I guess one could hide the reference to text/javascript behind a conditional comment; perhaps Justin Rogers could amend his example above?

    "Thanks for not using a single UPPERCASE tag! This actually makes your code sample look much more professional."

    HTML tags are not case sensitive. There is nothing unprofessional about uppercase HTML tags; they appear in uppercase in W3C specifications.

    Justin Rogers,

    "people don’t like my style"

    Nothing wrong with using HTML, but adding a TYPE attribute to SCRIPT and escaping end-tag open delimiters (</) within SCRIPT are not matters of style. On the later point, please consult:

    http://www.w3.org/TR/html4/types.html#h-6.2

    Your first SCRIPT element technically ends only six lines in, at:

    markupBuilder.push("</

    These are simple matters of writing standard HTML or writing gibberish. Please fix your example before too many people copy and paste it verbatim into their markup. That’s what the INS element is for, after all. :)

    (If I wanted to whinge about "style", I might suggest that it is always better to use external scripts to separate content from behaviour: http://www.sitepoint.com/print/javascript-from-scratch .)

    Michael Bolin:

    "instead of ‘blitzing’ the new HTML into the DOM, you would be gradually updating the DOM, which may have undesirable visual effects)."

    Why not use DocumentFragment to build up a DOM section out of sight, then insert it all in one go?

    TMaster:

    "What is the current suggested way to report non-critical bugs in IE7?"

    Phone support and the microsoft.public.internetexplorer.general newsgroup (yes, the closure of the public bug tracker does suck):

    http://www.microsoft.com/windows/ie/support/default.mspx#ie7Support

    Kris Zyp,

    "innerHTML [is] probably one of mostly widely implemented DOM interactions that is available, regardless of what W3C has to say about it."

    Maybe. But not all implementations are the same, as Ian Hickson has found while trying to write a backwards compatible, cross-browser specification for innerHTML for Web Applications 1.0:

    ln.hixie.ch/?start=1158969783&count=1

    Again, according to the Mozilla Developer Center: "when text is entered into a text input, IE will change the value attribute of the input’s innerHTML property but Gecko browsers do not".

    developer.mozilla.org/en/docs/DOM:element.innerHTML

  39. Jace says:

    @Benjamin Hawkes-Lewis

    Lower-case text compresses better than upper-case reducing Internet congestion…

  40. stanley says:

    Why not make JScript parser more clever, or make a JScript code optimizer?

  41. Benjamin Hawkes-Lewis says:

    @Jace

    "Lower-case text compresses better than upper-case reducing Internet congestion"

    So Web Optimization’s study appears to show ( http://www.websiteoptimization.com/speed/tweak/lowercase/ ), although their report confuses upper-case and mixed-case markup. Still, the logical advantage of lower-case markup, as far as I can gather, lies in the facts that:

    1. GZIP encoding depends on the repetition of character sequences.

    2. Character sequences like "table" are more likely to occur than "TABLE" in the content of the page.

    However, removing whitespace from your code and obfuscating JavaScript also reduces congestion. But to maximize code readability, such techniques should only be applied to served content and don’t really belong in maintained code or code samples. Whether the compression gains are generally worth obfuscating markup and code that users may wish to read and modify could be questioned. But I grant you that using all lower-case markup costs little in readability and gains a little in compressibility.

  42. Dao says:

    > But I grant you that using all lower-case markup costs little in readability and […]

    It doesn’t cost anything in readability. In fact, a typography rule is to avoid uppercase text because it’s hard to read.

  43. Andre says:

    Can anybody explaing me the problem with "window.OBJECT" instead of "OBJECT" at this post?

    http://weblogs.asp.net/mschwarz/archive/2006/11/17/javascript-performance-access-to-global-variables-part-1.aspx

  44. Benjamin Hawkes-Lewis says:

    Dao,

    "It doesn’t cost anything in readability. In fact, a typography rule is to avoid uppercase text because it’s hard to read."

    Yes, that’s a good point, one should avoid upper-case text for lengthy passages because it’s hard to read. But upper-case text works GREAT as a formatting to distinguish a special type of text intermixed with other text (see what I did there). So while the tags themselves may be (slightly) less readable, it’s easier to distinguish them amidst the text content, which arguably increases the scanability of the HTML as a whole.

    But like I say, it’s only a slight advantage. It’s not enough to make me want to use upper-case text personally. (But then I (mostly) switched from XHTML 1.0 served as text/html to HTML 4.01, so I’m habituated to lower-case markup anyway.)

  45. Tino Zijdel says:

    Apologies in advance for a lengthy post

    Justin, first of all I would like to comment on your ‘style’. I really do appreciate your effort but their are certain things you need to keep in mind when writing about performance recommendations. Any article about this subject should come with a big red warning label saying ‘beware of premature optimization and browser-specific implementations’. Also I object against using the term ‘recommendations’: most of the examples should not be considered good practices and you should only resort to certain optimization techniques when you have a compelling reason to do so. In 99% of all cases optimization on this level is not required and should be avoided at all cost to maintain readability of your code; f.i. using an array to do simple string-concatenation is completely illogical (more on that later).

    Secondly I object to using propriety techniques in examples, especially when they are completely unrelated to what you want to explain. You should always try to use standard techniques or when you want to explain something that is related to any propriety technique put another big red label next to it saying that it is browser-specific. Funny thing is that in some of your examples using a standards technique will actually perform far better (more on that later).

    In general when you use examples to show optimizations you should make sure that the example itself is optimized in every single way. I would like to demonstrate that in the explanation of the Array.join technique where you use the push method:

    markupBuilder.push(‘somestring’);

    now this involves a method call which is actually more costly than doing this:

    markupBuilder[markupBuilder.length] = ‘somestring’;

    Now I did some research into the general slowness of string concetenation in IE’s JScript implementation. It seems that when using strings smaller than 64KB there is no real performance issue, only beyond 64KB concatenation suddenly becomes 15 times slower (but is still linear). This is clearly an implementation issue that is specific to IE’s JScript, other browsers don’t suffer from this and just using the + operator performs best in these. So basically if you need to work with large strings and run into this IE-specific problem you should also apply this technique for IE only, for instance by using conditional compilation.

    Now let’s look at an example that involves loops:

    for(var i = 0; i < tokenizer.length; i++) {}

    here every iteration you need to check the length property of the tokenizer object which is slightly more costly than checking with a local variable. So you may want to rewrite this to:

    for(var i = 0, l = tokenizer.length; i < l; i++) {}

    or when order doesn’t matter even to this:

    var i = tokenizer.length;

    while (i–) {}

    Onto the use of propriety techniques: innerHTML

    innerHTML is like a sledgehammer, it’s great for manipulating large chunks of markup, but when you need to manipulate only a textNode you really should be using Element.firstChild.nodeValue which is around 6 times faster in IE. In your example you also insert a BR-element but if you had used a PRE-element i.s.o. a DIV for the output messages that would also not be necessary since you can than just use a linefeed.

    Furthermore in your example each time you reference ‘output’ a lookup needs to be done. I thought you explained in your previous article that it is much better to cache that reference in a JS variable. That would also unjustify the need to use document.all-like lookups which, I admit, are slightly faster than using getElementById but since backwards compatibility with the ancient document.all object model is the root cause of many problems in IE with regards to DOM compliance it should be avoided at all cost so that one day it can be removed completely from IE.

    Now I wouldn’t want to rewrite my switches just yet. When such rewrite would mean trading a switch for a function call you will only see performance improvement when your switch-block contains more than a hundred or so cases; below that the added cost for the function call is more expensive than the plain lookup of the proper switch-case. So yet another example of premature optimization that should only be used in very specific cases and since HTML only has 91 different tagnames (including Q) I would still use a switch 😉

    A far better tip would be to put the cases that are likely to occur most frequently ‘on top’ in your switch.

    Oh, and yes, don’t use an Array for associative properties, use an Object.

    About my JSON comment: note that I didn’t say that a JSON parser that doesn’t rely on eval() would be faster. I simply don’t know because I haven’t made such a parser yet, but I may just follow up on that although I couldn’t convince Douglas Crockford to consider my (faster) alternatives for toJsonString() either…

    One last general remark: I feel that your examples are too big and complex to demonstrate the techniques at hand. Although it is nice to use real world-ish examples that should not be a goal in itself. The optimization tips now get overshadowed by the complexity of the examples themselves.

    So far for my ‘bashing’, I hope it’s helpfull :)

  46. Dao says:

    Nice post, Tino. Really helpful.

    Btw, I just realized that Date is instantiated and thrown away 8 times in perfTestDivs. I know, it’s only a test function and doesn’t really matter (although the instantiation time adds to each result and thus adulterates the relative result). Anyway, you should take care of things like that while talking about performance.

  47. According to the HTML 4.01 spec at http://www.w3.org/TR/REC-html40/about.html#h-1.2.1:

    "Element names are written in uppercase letters (e.g., BODY). Attribute names are written in lowercase letters (e.g., lang, onsubmit). Recall that in HTML, element and attribute names are case-insensitive; the convention is meant to encourage readability."

    Just because the spec says element names should be in all caps (and argues that this improves readability, to boot!), do you expect everyone to start following the spec when lowercase names also work and improve download times? It’s the same thing when it comes to using innerHTML instead of DOM operations.

    Also, Benjamin Hawkes-Lewis, I appreciate the suggestion about DocumentFragment, but I don’t believe it’s supported correctly on IE6:

    http://developer.mozilla.org/en/docs/Migrate_apps_from_Internet_Explorer_to_Mozilla#Document_fragments

    Also, if you build up a DocumentFragment with DOM operations, then you don’t get the performance benefits that you would get from using innerHTML.

  48. Tino Zijdel says:

    @Michael Bolin: that phrase you are quoting is about the conventions used within the specification document itself and is not a recommendation about actual markup. When I write about markup I also use uppercase; e.g. TABLE-element and such, but in actual markup I use lowercase tagnames.

  49. Fred says:

    Andre:

    Using window.object requires two identifiers to be resolved: firstly "window", then "object".  Removing "window" means you only need to resolve "object" (unless you want to circumvent a masking variable called "object" somewhere on the scope chain).

    Dao:

    In javascript, new Date() returns a date object set to the instant that it was created. It doesn’t keep time with the system clock therefore the only way to get the current time is to create another Date object.  Less than optimal? Yes, but what else is there?

    Don’t trust numbers less than 100ms since the resolution of the javascript Date object seems to be only about 15ms on most systems.

    http://www.merlyn.demon.co.uk/js-dates.htm#Ress

  50. Dao says:

    > Using window.object requires two identifiers to be resolved: firstly "window", then "object".  Removing "window" means you only need to resolve "object" (unless you want to circumvent a masking variable called "object" somewhere on the scope chain).

    But since window is definitely the global scope, using window.foo means that the engine doesn’t have to deal with scopes.

    > In javascript, new Date() returns a date object set to the instant that it was created.

    True, I forgot that (using Date rather seldom).

  51. Dao says:

    > Don’t trust numbers less than 100ms since the resolution of the javascript Date object seems to be only about 15ms on most systems.

    > http://www.merlyn.demon.co.uk/js-dates.htm#Ress

    Not sure how this reflects the instantiation time … What I know is that it doesn’t depend on the system only, e.g. SpiderMonkey had a performance issue with Date.

  52. lwz says:

    In my opinion, since JScript is executed by an interpreter, the JScript interpreter should be able to evaluate the string passed to the function eval without constructing a new script runtime and copying the context of the currently executing script. Is there anything hindering such an execution?

  53. elh4096 says:

    Although Dao is correct in saying var o = {}; is the correct way of creating an object, it turns out that this is more likely to trigger the garbage collector in IE than var o = new Array(); Eric Lippert detailed in his blog how the garbage collector in jscript works.

    http://blogs.msdn.com/ericlippert/archive/2003/09/17/53038.aspx

    It sounds like this may no longer be needed for jscript 5.7 but it definitely provides a noticable impromentent for scripts that create lots of objects in IE 6 and lower.

    In any case, I am pleased to see that MS is putting effort into was has appeared to me to be a very neglected area. Though I am hesitant to believe that this purely due to customer feedback and more like to do with internal MS projects like atlas (or whatever there ajax toolset is called) – purely speculative on my part though.

  54. taylor says:

    @all those quibbling about HTML tags,

    HTML tags in uppercase, is the quickest way to get someone to laugh at your code.

    Do a view source of any professional site (Google, MSN, Yahoo, etc.) Check out their source.  You won’t find <BODY> or <TABLE> or <DIV> tags, because they are associated directly with HTML from 1995.

  55. Benjamin Hawkes-Lewis says:

    "HTML tags in uppercase, is the quickest way to get someone to laugh at your code"

    If that "someone" judges things by appearances I guess.

    "Do a view source of any professional site (Google, MSN, Yahoo, etc.) Check out their source.  You won’t find <BODY> or <TABLE> or <DIV> tags, because they are associated directly with HTML from 1995."

    Depends what you mean by "professional". Most of the (web) "professional" sites have jumped on the faux-XHTML bandwagon, including MSN from your list.  For such sites, upper-case markup is is a matter of conformance not style.

    If you’d bothered to look at the (allegedly) "professional" source code for this very blog page you’re on now, you’d find that despite claiming (laughably) to be XHTML, it includes plenty of elements in upper-case (do a case-sensitive search for <BR>, <P>, <FONT>, <H6>, <B>, and so forth).

    If I were to look at Google or Yahoo, I would find more important issues with their site than the case of their markup. Google’s homepage has 50 validation errors; Yahoo’s has 41. (The MSN page validates, so well done whoever did that! You still should have used HTML 4.01 Strict and a much cleaner design though.)

    If you look at http://www.microsoft.com (which purports to be HTML 4.0 Transitional but naturally doesn’t validate), you’ll see <META>, <SCRIPT>, and <NOSCRIPT> all in upper-case. Or again, if you look at http://www.dell.com (which likewise claims to be HTML 4.0 Transitional but of course doesn’t validate), you’ll find <META>, <TITLE>, and <LINK> in upper-case. Or if you look at the homepage of IETF, you’ll see <FORM> and <INPUT> in upper-case.

    Case dismissed. 😉

  56. Benjamin Hawkes-Lewis says:

    "HTML tags in uppercase, is the quickest way to get someone to laugh at your code"

    If that "someone" judges things by appearances I guess.

    "Do a view source of any professional site (Google, MSN, Yahoo, etc.) Check out their source.  You won’t find <BODY> or <TABLE> or <DIV> tags, because they are associated directly with HTML from 1995."

    Depends what you mean by "professional". Most of the (web) "professional" sites have jumped on the faux-XHTML bandwagon, including MSN from your list.  For such sites, upper-case markup is is a matter of conformance not style.

    If you’d bothered to look at the (allegedly) "professional" source code for this very blog page you’re on now, you’d find that despite claiming (laughably) to be XHTML, it includes plenty of elements in upper-case (do a case-sensitive search for <BR>, <P>, <FONT>, <H6>, <B>, and so forth).

    If I were to look at Google or Yahoo, I would find more important issues with their site than the case of their markup. Google’s homepage has 50 validation errors; Yahoo’s has 41. (The MSN page validates, so well done whoever did that! You still should have used HTML 4.01 Strict and a much cleaner design though.)

    If you look at http://www.microsoft.com (which purports to be HTML 4.0 Transitional but naturally doesn’t validate), you’ll see <META>, <SCRIPT>, and <NOSCRIPT> all in upper-case. Or again, if you look at http://www.dell.com (which likewise claims to be HTML 4.0 Transitional but of course doesn’t validate), you’ll find <META>, <TITLE>, and <LINK> in upper-case. Or if you look at the homepage of IETF, you’ll see <FORM> and <INPUT> in upper-case.

    Case dismissed. 😉

  57. Benjamin Hawkes-Lewis says:

    "HTML tags in uppercase, is the quickest way to get someone to laugh at your code"

    If that "someone" judges things by appearances I guess.

    "Do a view source of any professional site (Google, MSN, Yahoo, etc.) Check out their source.  You won’t find <BODY> or <TABLE> or <DIV> tags, because they are associated directly with HTML from 1995."

    Depends what you mean by "professional". Most of the (web) "professional" sites have jumped on the faux-XHTML bandwagon, including MSN from your list. For such sites, upper-case markup is is a matter of conformance not style.

    If you’d bothered to look at the (allegedly) "professional" source code for this very blog page you’re on now, you’d find that despite claiming (laughably) to be XHTML, it includes plenty of elements in upper-case (do a case-sensitive search for <BR>, <P>, <FONT>, <H6>, <B>, and so forth).

    If I were to look at Google or Yahoo, I would find more important issues with their site than the case of their markup. Google’s homepage has 50 validation errors; Yahoo’s has 41. (The MSN page at least validates, so well done whoever did that!)

    If you look at http://www.microsoft.com (which purports to be HTML 4.0 Transitional but naturally doesn’t validate), you’ll see <META>, <SCRIPT>, and <NOSCRIPT> all in upper-case. Or again, if you look at http://www.dell.com (which likewise claims to be HTML 4.0 Transitional but of course doesn’t validate), you’ll find <META>, <TITLE>, and <LINK> in upper-case. Or if you look at the homepage of IETF, you’ll see <FORM> and <INPUT> in upper-case.

    Case dismissed. 😉

  58. Benjamin Hawkes-Lewis says:

    "HTML tags in uppercase, is the quickest way to get someone to laugh at your code"

    If that "someone" judges things by appearances I guess.

    "Do a view source of any professional site (Google, MSN, Yahoo, etc.) Check out their source.  You won’t find <BODY> or <TABLE> or <DIV> tags, because they are associated directly with HTML from 1995."

    Depends what you mean by "professional". Most of the (web) "professional" sites have jumped on the faux-XHTML bandwagon, including MSN from your list. For such sites, upper-case markup is is a matter of conformance not style.

    If you’d bothered to look at the (allegedly) "professional" source code for this very blog page you’re on now, you’d find that despite claiming (laughably) to be XHTML, it includes plenty of elements in upper-case (do a case-sensitive search for <BR>, <P>, <FONT>, <H6>, <B>, and so forth).

    If I were to look at Google or Yahoo, I would find more important issues with their site than the case of their markup. Google’s homepage has 50 validation errors; Yahoo’s has 41. (The MSN page at least validates, so well done whoever did that!)

    If you look at http://www.microsoft.com (which purports to be HTML 4.0 Transitional but naturally doesn’t validate), you’ll see <META>, <SCRIPT>, and <NOSCRIPT> all in upper-case. Or again, if you look at http://www.dell.com (which likewise claims to be HTML 4.0 Transitional but of course doesn’t validate), you’ll find <META>, <TITLE>, and <LINK> in upper-case. Or if you look at the homepage of IETF, you’ll see <FORM> and <INPUT> in upper-case.

    Case dismissed. 😉

  59. Benjamin Hawkes-Lewis says:

    Gargh… sorry for the repeat postings, folks. :( The site kept throwing up an error page. If anybody could delete the three extra ones that would be good.

  60. samuel says:

    this really does not seem gto be any more efficienyt.HOWEVER, I suppose it could prove itself to be most benefivcial in the future.

  61. Tino Zijdel says:

    It’s a real pity neither Peter nor Justin seem to be eager to comment on my feedback even though I tried to bring it mildly this time (obviously they also overlooked my comments in part 1 because that certainly wasn’t "good feedback" either). I won’t go as far though as to say that I think this is again typical Microsoft behavior…

    Please consider having your next item on this subject proofread by someone who knows something about the subject but isn’t solely Microsoft-minded/oriented.

    Oh yes, I tried a non-eval based parser for JSON in javascript but preliminary tests show that such a parser would be at least 10x slower than the eval-solution…

  62. Lex says:

    @Benjamin Hawkes-Lewis

    You are right, lots of large sites don’t comply with xhtml, or claim to be one thing, but are actually not.

    I think taylor was spot on when s/he identified the use of UPPERCASE tags with amateurs.  Anyone that is serious about web development, today (circa 2006) that is developing using upper case tags, might as well tell the world their HTML editor of choice is MS Word.

    yeah, you can create a web page/site with Word, but no professional would dream of doing so.

    Nothing against Word of course, it does help write great documents (once you kick clippy to the curb), but it wasn’t designed for making web pages.

    Lex

  63. Renzo Kooi says:

    As for string concatenation using an array, this is the simplest method I suppose:

    [‘you ‘,’can just ‘,’concatenate anything ‘,’like this ‘,’right?’].join(”)

    Another question that’s really annoying: IE7 messes up my tooltip script (see link) using a zoomed view. Would there be a hack to disable or modify the page zooming?

    regards/RK

  64. Benjamin Hawkes-Lewis says:

    "I think taylor was spot on when s/he identified the use of UPPERCASE tags with amateurs. Anyone that is serious about web development, today (circa 2006) that is developing using upper case tags, might as well tell the world their HTML editor of choice is MS Word"

    I’m somewhat suspicious of free-floating arguments from popularity ("Anyone"), authority ("serious"), and fashion ("circa 2006"), which aren’t couched directly in terms of either technical merits or at least recommendations from standards organizations (who, we live in hope, have considered such merits). The same relentless pursuit of the novel drives people to create broken "XHTML" pages.

    "Nothing against Word of course, it does help write great documents (once you kick clippy to the curb), but it wasn’t designed for making web pages."

    Or, rather, it /was/ designed for making web pages, but like most such programs it was designed with the wrong conceptual model for HTML+CSS (in other words, WYSIWIG) and without any serious attention to interoperability and accessibility.

  65. How to shield the zoom in and zoom out function for IE7, please tell me using the javascript code, thanks

  66. Alex says:

    It is maybe OT but how the appendChild work for IE7 ?

    I am able to add a tr and td to an existing table but IE7 never works with.

    It is really require to work only with FF2 ?

    Well, for testings:

    [code]<html>

    <head>

    <title>Test</title>

    <script type="text/javascript">

      <!–

    function fillme(){

      row = document.createElement(‘tr’);

      row.setAttribute(‘id’,’trel’);

      col1 = document.createElement(‘td’);

      col1.setAttribute(‘id’,’colnl’);

      col2 = document.createElement(‘td’);

      col2.setAttribute(‘id’,’coln2′);

      col3 = document.createElement(‘td’);

      col3.setAttribute(‘id’,’coln3′);

      col1.innerHTML = "TD 1 ";

      col2.innerHTML = "TD 2 ";

      col3.innerHTML = "TD 3 ";

      row.appendChild(col1);

      row.appendChild(col2);

      row.appendChild(col3);

      document.getElementById("eingabe").appendChild(row);

    }

      //–>

    </script>

    </head>

    <body>

    <table id="eingabe">

    </table>

    <script type="text/javascript">

      <!–

         fillme();

      //–>

    </script>

    </body>

    </html>[/code]

    I am really not happy about changes from the IE7-dev-Team between the last Beta and the first RC :(

  67. IEBlog says:

    Hello again, this is Peter Gurevich, Performance PM for IE. We have gotten a lot of good feedback from

  68. I’ve flagged a few links to noteworthy JavaScript posts over the last month. Yahoo! Video: Advanced…

  69. I’ve flagged a few links to noteworthy JavaScript posts over the last month. Yahoo! Video: Advanced JavaScript

  70. This is the first ever blog written by me in my entire life time. Let me take some time to introduce

  71. says:

    Peter Gurevich, Performance Programm Manager des IE7 Teams, hat seine dreiteilige Serie zu o.g. Thema

  72. Markus' Blog says:

    IE + JavaScript Performance Recommendations von Peter Gurevich, Programm Manager IE7 IE + JavaScript

  73. JavaScript est un langage " late binded " c’est à dire que chaque appel d’une propriété aura un coup

  74. JavaScript est un langage " late binded " c’est à dire que chaque appel d’une propriété aura un coût

  75. Thanks to everyone that attended the December DevCares event in Chicago last week. One of the topics…

  76. Recently someone asked me about the best practices for AJAX performance. Though this information is scattered