Wednesday, July 9th, 2008
Category: Performance
Kimble Young has created Webslug, the “hot or not of website performance.”
It was inspired by webwait but lets you compare the load times of sites and records every performance test for later analysis like browser used, country of origin, top competitors etc.
For example, comparing reddit to Digg:

It is useful to compare versions of your own site, too.
Friday, July 4th, 2008
Category: Performance

Mario Heiderich has released qUIpt, a library that uses the window.name property to store away useful data, in this case JavaScript.
How does it work?
- It checks for the contents of window.name while your page is being loaded.
- If there’s nothing inside the window.name cache the JS files defined by you are fetched via XHR
- The same happens if the users enters your site for the first time of his current browser session or if document.referrer is off-domain or empty
- After that the contents of window.name are being evaluated
- If the user requests the next page on your domain the JS files are directly taken from window.name - no more requests necessary
You can check out an example of it at work
Friday, June 27th, 2008
Category: Performance
Steve Souders has a wrap up on the Velocity conference that he co-chaired. He links to his favourite content from the show, which contains a lot of Ajax related work. It was really good to hear snippets form the show such as Eric Lawrence of Microsoft saying “we hope to make Steve’s book out of date” as we see browser vendors look more and more on performance.
- back-to-back demos of HTTPWatch, Fiddler, AOL PageTest, and Firebug
- Several talks about Firefox from Mike Connor and Internet Explorer from Eric Lawrence and Christian Stockwell (slides)
- Lessons Learned in Live Search Moving to and then Away from Ajax by Eric Schurman, Microsoft (slides)
- Jiffy: Open Source Performance Measurement and Instrumentation by Scott Ruthfield (great speaker), WhitePages.com (slides, video)
- Improving Netflix Performance by Bill Scott, Netflix (slides)
- Hotmail’s Performance Tuning Best Practices by Aladdin Nassar, Microsoft (slides)
- High-performance Ajax Applications by Julien Lecomte, Yahoo (slides)
- Image Optimization: How Many of These 7 Mistakes Are You Making by Stoyan Stefanov, Yahoo (slides)
Tuesday, June 24th, 2008
Category: Canvas
, Performance
Just after I posted about Ernest’s canvas experiment with photos he put something else up that tests the performance of rendering polygons with Canvas compared to other techniques.
The demo lets you run a live test, and view saved tests, comparing the Google Maps interface, which “currently draws polygons using VML for Internet Explorer, SVG for Firefox and image retrieval for Safari and Firefox linux.”

At first the results were surprising. The canvas version was magnitudes faster. However, then they worked out that the live Google Maps version is actually doing a lot more than just drawing the polygons, that being said, a commenter had a valid point:
If we analyze the rendering time of the markup alone, both SVG and VML are not necessarily slower than canvas and canvas+excanvas.js. So the difference in performance is due to the implementation of polygons before the markup is output which the canvas implementation is skipping.
That doesn’t make the experiment invalid. You didn’t show that Canvas is faster than SVG or VML.
But you did show that it’s possible to get much better polygon performance than the current API using a more direct to the metal approach - with whatever rendering engine. And people are crying out for faster polygons.
Category: Performance
, Rails
Eric Falcao has released Clientperf, a simple client-side Rails performance plugin.
The tool came about as Eric is giving a talk on “14 rules of high-performance websites in the typical rails mongrel/nginx stack, the main idea being to focus on some of the important implementation details when it comes to client-side performance optimization.”
As I was planning, I realized that there was no simple as in the we’re-all-spoiled-with-rails simple way to measure client download times in production. Now, there is clientperf. It’s just a start, but decent enough to benchmark the actual client performance impact of any optimizations you make.
How it works
It injects javascript into the page that takes a timestamp at the top of the page and at the bottom of the page. Once the browser is done downloading, evaluating and rendering all assets, clientperf makes one last image request to your server with the start time, end time and the URL. Piece of cake.

Category: Performance
, Yahoo!
Keeping in the performance vein, YSlow put a new version out in time for Firefox 3.
The new version includes:
- Firefox 3 and Firebug 1.2 beta support
- improved and simplified check for javascript minification
- different coloring for inline vs. external CSS and JS (”All CSS” and “All JS” features)
- clickable list of resources as a Table of Contents (”All CSS” and “All JS” features)
- improved colors and presentation in the “legend” of component pies under Stats
- fixed a bug where the same hostname with different port number was counted as a separate DNS lookup
- misc bugfixes and style tweaks
Monday, June 23rd, 2008
Category: Performance
Today is the kick off of the Velocity performance conference, and we are going to see a fair share of performance news over the next day or two.
To start out, Bill Scott (Rico/ex-Yahoo/now Netflix) has announced a new Firebug plugin, Jiffy that adds a new tab showing fine grained performance data. You want to know the time between the onunload of the previous page, the first rendering, time until onload, time after, and more.
This is where Jiffy-Web comes in. Jiffy-Web is a fine-grained and flexible website performance tracking and analysis suite written by Scott Ruthfield and the team at Whitepages.com.
The Firebug plugin uses that data, which it gets from the DOM JSON object, to do the visualization.

Bill wrote a detailed post on Measuring User Experience Performance that goes into the details behind this tool.
He goes into detail on how to measure things, and what can get in the way. For example, onunload:
The most logical place to measure the start of a request (”from Click”) is on the originating page (see A in figure above). The straighforward approach is to add a timing capture to the unload event (or onbeforeunload). More than one technique exist for persisting this measurement, but the most common way is to write the timing information (like URL, user agent, start time, etc.) to a cookie.
However, there is a downside to this methodology. If the user navigates to your home page from elsewhere (e.g., from a google search), then there will be no “start time” captured since the unload event never happened on your site. So we need a more consistent “start time”.
We address this by providing an alternate start time. We instrument a time capture at the very earliest point in the servlet that handles the request at the beginning of the response (see B in figure above). This guarantees that we will always have a start time. While it does miss the time it takes to handle the request, it ends up capturing the important part of the round trip time — from response generation outward.
There are a number of ways to save this information so that it can be passed along through the response cycle to finally be logged. You can write out a server-side cookie. You can generate JSON objects that get embedded in the page. You could even pass along parameters in the URL (though this would not be desirable for a number of reasons). The point is you will need a way to persist the data until it gets out to the generated page for logging.
Note that the absolute time captured here is in server clock time and not client clock time. There is no guarantee these values will be in sync. We will discuss how we handle this later.
He also talks about practical issues that he has found implementing this at Netflix, and when the data shows you the real truth:
Recently we fielded a different variation of our star ratings widget. While it cut the number of HTTP requests in half for large Queue pages (a good thing) it actually degraded performance. Having real time performance data let us narrow down on the culprit. This feedback loops is an excellent learning tool for performance. With our significant customer base, large number of daily page hits we can get a really reliable read on the performance our users are experiencing. As a side note, the median is the best way to summarize our measurements as it nicely takes care of the outliers (think of the widely varying bandwidths, different browser performance profiles that can all affect measurements.)
Thursday, June 12th, 2008
Category: JavaScript
, Performance
Omar AL Zabir of Pageflakes.com has posted on ensure, his JavaScript library that provides a handy function ensure which allows you to load JavaScript, HTML, CSS on-demand and then execute your code.
Ensure ensures that relevant JavaScript and HTML snippets are already in the browser DOM before executing your code that uses them.
For example:
JAVASCRIPT:
-
-
ensure( { js: "Some.js" }, function() {
-
SomeJS(); // The function SomeJS is available in Some.js only
-
});
-
You can also specify multiple Javascripts, html or CSS files to ensure all of them are made available before executing the code:
JAVASCRIPT:
-
-
ensure( { js: ["blockUI.js","popup.js"], html: ["popup.html", "blockUI.html"], css: ["blockUI.css", "popup.css"] }, function() {
-
BlockUI.show();
-
PopupManager.show();
-
});
-
Omar says:
Websites with rich client side effects (animations, validations, menus, popups) and Ajax websites require large amount of Javascript, HTML and CSS to be delivered to the browser on the same web page. Thus the initial loading time of a rich web page increases significantly as it takes quite some time to download the necessary components. Moreover, delivering all possible components upfront makes the page heavy and browser gets sluggish responding to actions. You sometimes see pull-down menus getting stuck, popups appearing slowly, window scroll feels sluggish and so on.
The solution is not to deliver all possible HTML, Javascript and CSS on initial load instead deliver them when needed. For example, when user hovers the mouse on menu bar, download necessary Javascript and CSS for the pull-down menu effect as well as the menu html that appears inside the pull-down. Similarly, if you have client side validations, deliver client side validation library, relevant warning HTML snippets and CSS when user clicks the 'submit' button. If you have a Ajax site which shows pages on demand, you can load the Ajax library itself only when user does the action that results in an Ajax call. Thus by breaking a complex page full of HTML, CSS and Javascript into smaller parts, you can significantly lower down the size of the initial delivery and thus load the initial page really fast and give user a fast smooth browsing experience.
There is a detailed writeup on how it all works, and it dovetails with the recent performance proposals around when to download resources (sometimes you may not want to wait for on demand loading of course).
Monday, June 9th, 2008
Category: IE
, JavaScript
, Performance

Tom Trenka has followed up his last post on String performance with a deep dive on IE that dispells the myth of Array.join.
Tom goes through tons of tests across versions of IE and using varying sizes of data.
In Conclusion
First things first—with the performance improvements with IE7, we no longer need to consider using an alternate path when doing large scale string operations; using Array.join in an iterative situation gives you no major advantages than using += in the same situation. In addition, the differences with IE6 were slight enough to allow you to not bother forking for that specific version.
The only time considering using an array as opposed to a string for these kind of operations is when you are aware that the fragments you are appending are very large (on the order of > 65536 bytes); doing this will cause the GC issues Dan Pupius talks about in his analysis of object allocation and the JScript garbage collector.
From there, we can progress to programming techniques—with Internet Explorer, it is much better to call Builder.append with as many arguments as possible than to simply iterate and push things in one at a time.
It is also better to start small; try to structure your string operations so that very large string operations are minimized. In this case, using a temporary buffer to assemble a set of strings together and then adding them to a much larger string is better than constantly adding small fragments to a larger string.
And as always, minimizing the size of an iteration will help get extra performance out of JScript.
The raw numbers have been made available to scour over.
Friday, June 6th, 2008
Category: JavaScript
, Performance
Bob Matsuoka has written a guest article on the topic of lazy script loading. Thanks so much Bob!
A recent article "Lazily load functionality via Unobtrusive Scripts" discussed how to lazily load Javascript script files by appending script elements to the HEAD tag.
While this works as expected, I've found that for best results, you should also consider tracking which scripts have been loaded in order to prevent re-loading an already loaded script, and more importantly supporting callbacks so that you can guarantee loading of scripts prior to calling functions that depend on that code.
NOTE: The example loader script, which has been tested in FF, IE, Safari, and Opera, uses prototype.js for DOM and array routines. I developed this originally for a project that already had prototype.js available, but it uses it only superficially. It should be simple to remove these references if you're not using prototype.js.
JAVASCRIPT:
-
-
/**
-
* Script lazy loader 0.5
-
* Copyright (c) 2008 Bob Matsuoka
-
*
-
* This program is free software; you can redistribute it and/or
-
* modify it under the terms of the GNU General Public License
-
* as published by the Free Software Foundation; either version 2
-
* of the License, or (at your option) any later version.
-
*/
-
-
var LazyLoader = {}; //namespace
-
LazyLoader.timer = {}; // contains timers for scripts
-
LazyLoader.scripts = []; // contains called script references
-
LazyLoader.load = function(url, callback) {
-
// handle object or path
-
var classname = null;
-
var properties = null;
-
try {
-
// make sure we only load once
-
if ($A(LazyLoader.scripts).indexOf(url) == -1) {
-
// note that we loaded already
-
LazyLoader.scripts.push(url);
-
var script = document.createElement("script");
-
script.src = url;
-
script.type = "text/javascript";
-
$$("head")[0].appendChild(script); // add script tag to head element
-
-
// was a callback requested
-
if (callback) {
-
// test for onreadystatechange to trigger callback
-
script.onreadystatechange = function () {
-
if (script.readyState == 'loaded' || script.readyState == 'complete') {
-
callback();
-
}
-
}
-
// test for onload to trigger callback
-
script.onload = function () {
-
callback();
-
return;
-
}
-
// safari doesn't support either onload or readystate, create a timer
-
// only way to do this in safari
-
if ((Prototype.Browser.WebKit && !navigator.userAgent.match(/Version\/3/)) || Prototype.Browser.Opera) { // sniff
-
LazyLoader.timer[url] = setInterval(function() {
-
if (/loaded|complete/.test(document.readyState)) {
-
clearInterval(LazyLoader.timer[url]);
-
callback(); // call the callback handler
-
}
-
}, 10);
-
}
-
}
-
} else {
-
if (callback) { callback(); }
-
}
-
} catch (e) {
-
alert(e);
-
}
-
}
-
Download the full source and example project.
Tracking Loaded Scripts
A common use of a lazy loader is in conjunction with "require" type function that allows you to specify which scripts are needed for a particular script to execute. Since library scripts are often called by more than one script, I thought it important to allow my lazy loader to track which scripts have already been loaded on a page to prevent unnecessary re-loading.
In this example, I've created the LazyLoader.scripts array. As each script is called, this script src is tested against the array of scripts already called, and if it exists, the script is not re-loaded, but its callback is executed. This allows you to call any required script as often as needed with impunity.
Supporting Callbacks
A more important addition is support for callbacks. It is my experience that with anything more than the simplest scripts, you cannot guarantee that a script is available for use unless it is called as part of a callback tied to the loading process. Unfortunately most of the browsers handle script onload events slightly differently. The examples I've provided should work for Firefox, Safari, and IE.
The basic logic for supporting callbacks is to allow a closure to be passed to the lazy loader. The function is then bound to the script event triggered by its loading. FF and Safari 3 support the "onload" event. IE supports the onreadystatechange event, and requires further testing of the state for either 'loaded' or 'complete' (depending on whether the script is cached).
Supporting callbacks in Safari 2 and Opera require a slight wrinkle, since neither support "onload" or "onreadystatechange" script events. For these browsers, you need to set a quick interval script to test document.readyState for "loaded" or "complete". Once ready, the interval can be cleared and the callback executed (I use a different interval for each script loaded, but I'm not sure that's necessary, since we are only testing the document object, not the state of the individual scripts).
Calling The Loader
Calling the loader is straightforward. This implementation is setup as a static function using a namespace. Here is an example without a callback:
JAVASCRIPT:
-
-
LazyLoader.load('js/myscript1.js');
-
Here is an example with a callback:
JAVASCRIPT:
-
-
LazyLoader.load('js/myscript2.js', function(){
-
var myobj = new MyObject('myobj');
-
});
-
In the second example, the "myobj" instance of MyObject is only created after js/myscript2.js is loaded. You can also daisychain loaders by including them in the callback function.
Conclusion
I've used this technique for nearly a year with good results. We have a very large library of objects and functions that are only needed for specific pages that share the same "layout", and this allows us to call the scripts properly (in the HEAD tag, as opposed to including script references within the body of the page) and cleanly. We use this function in conjunction with a "require" function to script dependencies can be shown cleanly.
A script loader also works very nicely when used in conjunction with form-based script loading, which is a technique we use to declaratively reference script objects and bind them to HTML forms, as well as pass in server-side variables. I will discuss this in a follow-up article.
Thursday, June 5th, 2008
Category: Performance
"innerHTML is 35 times faster than DOM."
"DOM methods are just as fast!"
This is a constant argument, and statistics hardly help ;)
Laurens Holst of Backbase has taken a detailed look at the issue as he drew up his own benchmark.
People keep mentioning performance as an argument for using innerHTML, citing that article, so I thought I’d go and see what the reason was for the difference between his and my findings. It turns out that the benchmark has some flaws that skew the results very much in favour of innerHTML, which I’ll point out.
- Content is never escaped
- Selective HTML usage
- XML is much faster than HTML
He re-ran the benchmarks on his system using the new browsers and got the following results:

Tuesday, June 3rd, 2008
Category: JavaScript
, Performance
, Safari