Thursday, January 28th, 2010
Category: Browsers, Canvas, Performance

The Freeciv.net crew has benchmarked a path in their canvas game. It is one data point, and tests more than just Canvas itself because a lot of code is running in the game. Thus, it ends up testing the union of a particular JavaScript path and the rendering of the canvas.
Here are the results:

With Bespin we had slightly different results, and the bulk of the bottleneck was in the blitting of the canvas. Optimizations were made to canvas over the initial phase of Bespin so the various browsers would leap frog each other. Good times :)
Friday, January 15th, 2010
Category: CSS, JavaScript, PHP, Performance
I am right now working on a high-traffic project that will run in a sandbox that doesn't allow me to pull third party JavaScript or use canvas/Flash. Yet I need to generate bar charts from a set of data.

The solution to me was to create the charts from HTML using CSS. There have been some solutions for this problem already but I wanted something very simple and easy to maintain. Hence all the markup I am using is this:
XML:
-
<ul>
-
<li><span>400</span></li>
-
<li><span>20</span></li>
-
<li><span>30</span></li>
-
<li><span>233</span></li>
-
</ul>
Instead of hard-coding any of the trickery necessary I wrote a PHP script to generate the HTML, the styles and do all the math. So all that is needed to render one of the charts is the following code:
PHP:
-
<?php
-
$values = '400,20,30,233,312,78,20,67';
-
$height = 100;
-
$width = 600;
-
$bargap = 0;
-
include('csscharts.php');
-
?>
Of course, this can also be turned into a web service - you can get the chart with the following URL:
http://icant.co.uk/csscharts/csscharts.php?values=400,20,30,233,312,78,20,67&height=100&width=600&bargap=0
And if you specify JSON as the format you get it with a callback to a function called csscharts:
http://icant.co.uk/csscharts/csscharts.php?values=400,20,30,233,312,78,20,67&format=json
JAVASCRIPT:
-
csscharts(
-
{
-
chart:"<ul class=\"barchart\" [… the rest of the html …]</ul>"
-
}
-
)
That way you can use it in JavaScript:
JAVASCRIPT:
-
<script>
-
function csscharts(o){
-
var container = document.getElementById('container');
-
c.innerHTML = o.chart + c.innerHTML;
-
}
-
</script>
-
<script src="http://icant.co.uk/csscharts/csscharts.php?values=400,20,30,233,312,78,20,67&format=json"></script>
You can see some demos here, get detailed info about the CSS trickery used and of course download the code on GitHub.
Wednesday, December 30th, 2009
Category: Performance
The WebKit Inspector tool has a new tab, the Audits panel which aims to be like Google PageSpeed and YSlow! built right in.
A little crude, but good to see:


Saturday, December 12th, 2009
Category: Performance
Rob Flaherty has done a little experimenting with data URIs and performance. The study only looked at Firefox 3.5 with empty cache, but the results were interesting for the questions they raise as much as the answers the provide.
He used a CSS file with 31 images and converted them all to data URIs using Nick Zakas's CSSEmbed. For an extra variant, he used DURIS to extract the data URIs to a separate CSS file so that the basic CSS in <head> becomes much smaller and therefore loads much faster.
All three scenarios yielded similar performance - with HTTPWatch, the times were 1.35s, 1.13s, and 1.13s. So the two data URI scenarios were only marginally better. But more interestingly, a commenter from South Africa chimed in with wildly different results (using Firebug): 4.04s, 1.44s, 1.92s. The implication is clear: latency can be a big factor in some cases, and round-tripping to fetch 31 images is going to bring that out.
Another interesting factor is perceived speed. This is, after all, arguably the most important thing when it comes to performance. Although the two data URI scenarios completed in the same speed, the second setup felt faster because it got the images out of the way and allowed the main stylesheet to load fast. The data URI images were then loaded in a stylesheet at the bottom of the page, after a script had been loaded.
The study also raises questions about data URI loading. A commenter posted a waterfall showing the data URI images take significantly longer to load than regular downloaded images. This is the kind of thing that needs more research and why the study is interesting because of the questions it raises.
Rob also posted a study recently on background-image performance in various browsers.
Thursday, December 3rd, 2009
Category: Editorial, Performance

"View Source is your friend", we've learned countless times as web developers. It's something special about web development that we can seamlessly lift the covers on anything we see and find out how the sausage is made. And it gets even better with great tools to interrogate the system in real-time. This capability has helped us evolve practices and patterns, and contributed to the production of many a fine browser extension and Greasemonkey script.
Our friend might sadly be going the way of the blink tag. View Source has always worked because the standard development model is to put up some static Javascript files on a server somewhere and serve them out. That model is changing though; performance is a very hot topic right now, and View Source is playing victim to that trend.
Google's Let's Make the Web Faster initiative is a case in point. Here is a multi-pronged attack on the performance issue, involving new protocols (SPDY), tools (PageSpeed), browser improvements (Chrome), on-demand loading (Closure), and - most pertinent - compression techniques (Closure again). And we ain't seen nothing yet; there's every reason to believe Google will soon be putting its money where its mouth is, by rewarding faster sites with higher rankings. (I guess I was alone in assuming they always did that.) While performance should always be a consideration for site owners, a dangling SEO carrot would no doubt convert the best of intentions into the most concrete of actions.
Site owners can't (much) control factors such as browser choice and browser efficiency, but they can get their own performance-fu in order, and code compression is low-hanging fruit. Looking at the top 20-ranked sites, filtering only English-language sites, I found the very top guys (Google, Facebook, Yahoo, YouTube, Windows Live) predominately using Javascript compression, with the others not using it much, if at all. I expect most of them to be using it in the next 12-24 months.
In addition to compression, there is also obfuscation. With Javascript being used for more complex tasks and replacing desktop functionality, more companies will be wondering about all that intellectual property sitting in plain view. (And let's not mention the security-by-obscurity fans, who will also go this route, however flawed their thinking.)
Is it all bad? No. There's a much healthier respect for plain old semantic HTML these days, which means HTML documents should be View Sourcier now than ever before. (CSS, not so much, with compression also likely to grow.) If I had to choose between one or the other, I'd take clear HTML over clear Javascript. Also, we will probably find the majority of sites in the long tail won't feel the need to do anything about their code (but the ones who do make efforts are probably the ones with the most interesting things to look at). Also, the aforementioned tools, which do things like XHR sniffing, will help us to understand from a "black box" perspective even if we can't peer into the code. Hopefully, there will also be more attention paid towards Javascript beautifiers as well, to make sense of compressed code.
I can't speculate on the waning of View Source without mentioning the tremendous counter-balancing act played out by Open Source. From the get-go, open source has played a vital role in Ajax, with individuals and companies releasing code for all sorts of reasons. Most of this is library and framework code, rather than production-ready applications, so we might lose something there, but we still have much to gain from the ever-growing corpus of code that's out there, free to be studied and incorporated into our own applications.
Wednesday, December 2nd, 2009
Category: Performance
I heard a huge cheer from the Internet today and found that Google Analytics has launched async mode which finally unclogs our browsers from blocking.
Steve Souders must have had the loudest cheer, and wrote up his view:
The pain of loading JavaScript files is that they block the page from rendering and block other resources from downloading. There are workarounds to these problems. Chapter 4 of Even Faster Web Sites describes six techniques for Loading Scripts Without Blocking. One of those, the Script DOM Element approach, is the technique used in the new Google Analytics async pattern. Google Analytics’ ga.js file is a perfect example of a script that should be loaded asynchronously - it doesn’t add any content to the page, so we want to load it without blocking the images and stylesheets that give users what they really came to see.
Improved Uptime
What happens if a script takes a long time to load, or fails to load? Because scripts block rendering, users are left staring at an empty page. Google Analytics has an amazing infrastructure behind it, but any resource, especially from third parties, should be added cautiously. It’s great that the GA team is evangelizing a pattern that allows the web site to render while ga.js is being downloaded.
To get going, simply change your ga script code to follow the pattern:
JAVASCRIPT:
-
-
var _gaq = _gaq || [];
-
_gaq.push(['_setAccount', 'UA-XXXXX-X']);
-
_gaq.push(['_trackPageview']);
-
-
(function() {
-
var ga = document.createElement('script');
-
ga.src = ('https:' == document.location.protocol ?
-
'https://ssl' : 'http://www') +
-
'.google-analytics.com/ga.js';
-
ga.setAttribute('async', 'true');
-
document.documentElement.firstChild.appendChild(ga);
-
})();
-
It’s extremely cool to see this pattern being evangelized for such a major piece of the Internet. A few items of note:
- Obviously, you have to replace “UA-XXXXX-X” with your ID.
- Since ga.js is being loaded asynchronously, there has to be a way for web site owners to couple their desired GA functions with the code when it finishes loading. This is done by pushing commands onto the Google Analytics queue object, _gaq.
- Once all your callback commands are queued up, the ga.js script gets loaded. This is wrapped inside an anonymous function to avoid any namespace conflicts.
- Inside the anonymous function is where we see the Script DOM Element approach being used - with two nice improvements. A ’script’ element is created and its SRC is set to the appropriate ga.js URL. Looking ahead to support of asynchronous scripts in HTML5, the ‘async’ attribute is set to ‘true’. Very nice! The main benefit of this is it tells the browser that subsequent scripts can be executed immediately - they don’t have to wait for ga.js. The last line adds the script element to the DOM. This is what triggers the actual download of ga.js. In most of my code I do document.getElementsByTagName(”head”)[0].appendChild, but that fails if the document doesn’t have a head element. This is a more robust implementation.
Monday, November 30th, 2009
Category: Performance
Stoyan Stefanov is all about the performance of web products. One small tool that gives you a bit of insight as to where you can optimize is a new bookmarklet he released today called statsy.
If you run statsy on a web site you get the following insights:
JS attributes (e.g. onclick) - this is the sum of all onclick, onmouseover and so on including the attribute names. So for example <a onclick="#"> is 11 characters (bytes) of JavaScript attributes code
CSS style attributes - the sum of all style="..."
Inline JS - the sum of all the contents of all script tags (excluding the tag itself)
Inline CSS - sum of all <style> tag contents
All innerHTML - this is document.documentElement.innerHTML.length, it should be close to the ungzipped size of a page, provided the page is not doing a lot of DOM manipulation
# DOM elements - the total number of elements on the page is counted simply using document.getElementsByTagName('*').length
On Ajaxian, this is the result:

You can install statsy by dragging the following link to your link bar: Statsy and the source is also available.
Nothing earth-shattering but a good tool to use together with YSLow or PageSpeed.
Category: Performance
We have posted about LABjs before, the library that aims to be able to effectively load any script resource(s), from any location, into any page, at any time. It loads them all as parallel as the browser will allow, but maintains execution order when you express the need to do so in the usage of the API, for keeping dependencies safe.
At JSConf.EU in Berlin, I saw Steve Souders and Kyle Simpson riffing on how to make LABjs follow the research that Steve (in his newest book) and Kyle have done.
There were issues in the past, but we now have a new release of LABjs that does the right thing, as long as you wait():
JAVASCRIPT:
-
-
$LAB
-
.script("framework.js").wait()
-
.script("plugin.framework.js")
-
.script("myplugin.framework.js").wait()
-
.script("init.js");
-
Give it a whirl, and read the full post for details on performance and issues with flashing in before behaviour has been added... which leads us to the cavaet on jQuery and DOM ready.
Also, if you think that you should be just concat'ing all of the files into one, see why Kyle thinks you should potentially think again.
As I wrote this another library called NBL came in from "Berklee". He told us:
The other day I tasked myself with rewriting our company's website in HTML5 and I really wanted to improve performance all across the board. So after rewriting the HTML and CSS, I looked to JavaScript lazy loading to increase performance. After searching for a small library to do this and not finding anything not requiring jQuery, or unable to handle network timeouts, I decide to write my own non-blocking lazy loader.
It's called NBL and comes down to 1187 bytes minified. It runs stand-alone and has several options that I could not find in any other library:
1. It can load plugins for your JavaScript framework *after* the framework has been loaded (jQuery is considered the default, but you can override it with any other framework and keep this behaviour).
2. You can provide a callback function that fires when all scripts are loaded, or if you use jQuery, the callback will be fired by jQuery's document.ready() function (unless the page finishes before jQuery initialises, in which case it fires when all scripts are loaded).
3. In case of network latency (or faulty urls), NBL will fire the callback function after a timeout (by default 1200ms).
4. It does not need to be called, it can be configured completely from the script tag itself, like this:
HTML:
-
-
<script type="text/javascript" src="nbl.js" opt="{ urchin: 'http://www.google-analytics.com/urchin.js',
-
plugins: [ 'jquery.lightbox.min.js', 'jquery.carousel.min.js' ], ready: my_ready_function }" />
-
Friday, November 20th, 2009
Category: Performance
Jake explains no-one likes waiting, and people are multi-threaded (except when they have to sneeze). Yet, we're stuck with a single-threaded language for the most part; and we still face the legacy of a DOM standard from another era (DOM Level 1 - 1997). This talk provides some optimisation tips, backed by Jake's cross-browser experiments.
Jake's slides and research are online.
Optimise Where it Matters
Jake explains the importance of speeding things up where it really matters.
Doug Crockford has pointed out that in Javascript, bitwise operations aren't close to the hardware, which stands in contrast to other languages. In fact, if you look at it, bitwise operations can still be faster than alternative operations; Jake shows an example where bitwise parsing of hex codes is faster than bitwise. The question is, how much faster? In many cases, such as this example, your energy is better spent on optimising big things.
Avoid eval() Where Possible
Jake says avoid eval() where possible. Thinking about what functions eval, here's a brain teaser: what will the following output?
JAVASCRIPT:
-
-
var msg = "spatchcock";
-
function doStuff() {
-
alert(msg);
-
if (false) {
-
var msg="spotted dick";
-
}
-
}
-
doStuff();
-
Wait for it ... the answer is "undefined". Javascript does look ahead and create space for the local variable. So during the running of the function, there's no need to allocate space for the variable and the browser can optimise for that, but if you use "eval", the optimisation goes away. So avoid eval().
Prefer innerHTML to DOM
Jake shows a comparison of innerHTML versus DOM Level 1. In IE, DOM manipulation is much slower, because of the sync process between the two. The differential gets even worse when creating elements. Webkit has optimised sync between HTML and DOM, hence less difference, so it's not as bad, but create example is still slower with DOM. So from a performance perspective, best practice is construct the HTML and use innerHTML.
Selectors
It's educational to look at the implementation of selector libraries. Jake shows a comparison - IE7 is vastly more slow in this case. It doesn't support getElementsByClassName, querySelectorAll, evaluate; and it does support getElementById, but that's not used by sizzle for this query. So getElementsByTagName is all that's left; and if you knew that, and the implications, you could have made the query much faster.
Benchmarking
Pretty simple.
JAVASCRIPT:
-
-
var duration;
-
start = new Date()
-
thingToTest();
-
duration = new Date() - start;
-
However, timing isn't so accurate, so stick it in a function and run it many times.
Too easy ... so go benchmark and report your findings.
Tuesday, November 17th, 2009
Category: Browsers, Performance
HTML:
-
-
<link rel="resource-package" href="site-resources.zip" />
-
What if we could agree on a simple backwards compatible approach to packaging Web resources so the browser could suck down the puppies in one go?
Alexander Limi (of Plone and Firefox UX fame) has been thinking about this for awhile, and has gotten his latest proposal out there which defines a simple way to package things.
It builds on existing tech: zip, manifests, and the like.... and degrades nicely.
This is so much nicer than spriting hacks, but does have its own issues:
- In theory the browser could sometimes render faster by grabbing items in parallel
- Mobile caches may be messed up (as larger than a cache size, like say iPhone's 256k)
- What if the zip gets out of date with the other resources?
- Ideally tools (and in fact even web server modules) would auto generate this stuff
Although not perfect, for the majority case this could be a real boon to performance. What do you say Steve?
Oh, and it sounds like Firefox will implement this in 3.7!
Thursday, November 12th, 2009
Category: Google, Performance
Mike Belshe of Google has been working on SPDY an optimized use of HTTP:
It is designed specifically for minimizing latency through features such as multiplexed streams, request prioritization and HTTP header compression.
We started working on SPDY while exploring ways to optimize the way browsers and servers communicate. Today, web clients and servers speak HTTP. HTTP is an elegantly simple protocol that emerged as a web standard in 1996 after a series of experiments. HTTP has served the web incredibly well. We want to continue building on the web's tradition of experimentation and optimization, to further support the evolution of websites and browsers. So over the last few months, a few of us here at Google have been experimenting with new ways for web browsers and servers to speak to each other, resulting in a prototype web server and Google Chrome client with SPDY support.
So far we have only tested SPDY in lab conditions. The initial results are very encouraging: when we download the top 25 websites over simulated home network connections, we see a significant improvement in performance - pages loaded up to 55% faster. There is still a lot of work we need to do to evaluate the performance of SPDY in real-world conditions. However, we believe that we have reached the stage where our small team could benefit from the active participation, feedback and assistance of the web community.
It is great to see this in the wild. We have seen delta compression from Google before (used in Google Toolbar but not talked about too much) but I am glad to see this getting out there early stage, which gives all browsers/servers a chance to participate and play.
However, I have an issue with one line of code.... ;)
Great write-ups here:
Wednesday, November 4th, 2009
Category: Performance, jQuery
When your browser freezes on you on some random web page, there's a pretty good chance its caused by the very JavaScript designed to improve your experience.
Good 'ole JavaScript performance. Sebastian Ruiz of Atlassian recently worked on a UI rewrite of two of their products (FishEye and Crucible) and found some interesting solutions to problems that came up:
The event binder
A simple jQuery event bind selector might look like this:
JAVASCRIPT:
-
-
$(document).ready(function () {
-
$(".alert-on-click").bind("click", function () {
-
alert("Clicked element " + this);
-
});
-
});
-
This is a rather standard method of binding functions to events with jQuery. It's easy and it's elegant. When the html document has finished loading, the anonymous function is executed. This will find all elements which have the class 'alert-on-click' in the document, and binds a function which is triggered on a click event.
Slow class selectors
This method can be problematic with large html documents with thousands of DOM elements. Web browsers which aren't able to do efficient evaluations on class based selectors are seriously disadvantaged here as they need to trawl through the entire document tree to find the elements. Other browsers are better off, but it's still a high cost
operation relative to the super fast id based selector.
The cost of the bind
For moment, imagine that you are Crucible as a web application. You've been asked to display a review which has 10,000 lines of code visible. Seems simple - throw each of the lines into a table for easy and nice rendering. Then you need to make sure that whenever the user clicks on lines of code, that they are able to create a comment on that requested line. Simple! Bind an a click event handler to the source lines.
JAVASCRIPT:
-
-
$(document).ready(function () {
-
$("tr.sourceLine").bind("click", showCommentBoxFn);
-
});
-
However in this case the browser needs to find 10,000 tr elements, and make 10,000 bind calls. This is noticeably expensive and will slow down the load of the page. Furthermore, it's easy to miss that for memory management reasons, jQuery also unbinds all bound elements on a click away from a page. That means a slow load, but also a slow unload.
How to count binds
Here's an easy trick to find out just how many bind and calls you are making when loading your page. Insert this point cut into your JavaScript to add some debugging to jQuery bind events. You'll need firebug installed and enabled to see the output.
JAVASCRIPT:
-
-
jQuery.fn.bind = function (bind) {
-
return function () {
-
console.count("jQuery bind count");
-
console.log("jQuery bind %o", this);
-
return bind.apply(this, arguments);
-
};
-
}(jQuery.fn.bind);
-

The team moved away to the not-so-recently jQuery addition, live queries:
JAVASCRIPT:
-
-
$(document).ready(function () {
-
$("tr.sourceLine").live("click", showCommentBoxFn);
-
});
-
and found a few pitfalls:
Binding with live events still needs to evaluate the selector expression, which means that $(".class").live() can still be very slow if the DOM is large. We worked around this by loading the large chunks of data with an ajax call after initialising the page view and running our live event binding.
Using live events on mouse events (click, dblclick, mousepress etc) accepts events from the right mouse button when they normally aren't desirable. For example, a right click on a link to copy a gracefully degrading target url would cause the bound event to fire. We solved this by reimplementing jQuery's live function to ignore events caused by right clicks - see the source
Quasi race conditions due to the non deterministic execution order of live events. If an element matches more than one live event selector, then the order which in these event functions are executed is not guaranteed. For example:
JAVASCRIPT:
-
-
$(document).ready(function () {
-
$("div.comment").live("click", function () {
-
markCommentAsRead();
-
});
-
-
$("div.comment a.reply").live("click", function () {
-
replyToComment();
-
// there is no way to prevent a propagation to div.comment
-
});
-
});
-
In this case, when the <a class="reply"> link is clicked, both replyToComment() and markCommentAsRead() will be executed.
3.1 rating from 105 votes
Tuesday, November 3rd, 2009
Category: CSS, JavaScript, Performance
It does not matter if we have the latest CPU able to devour every single bit of a web page, round trip and network delay is still the real bottleneck of whatever website and Steve Souder knows it so well that he summarize best practices in 66 slides.
And That's Not All!
Steve slides are mainly focused on JavaScript techniques able to download simultaneous files without blocking download first, and layout render after. He is generally right about his assumptions, but as is for everything, there are cases and cases. Please let me share here my thoughts about performances, not necessary too hard if we perfectly know what we are doing, but somehow hard to make it that perfect as well!
Image Sprites Rule
A common technique to avoid unnecessary requests to the server is the usage of image sprites. This means that rather than 16 images, as example, we could have a single 4x4 grid with all required images positioned when necessary via CSS and better compressed. Nothing new? Well, a common side effect of this technique is that if the current page will use only 4 out of 16 images, the total download size will be bigger than required one and the total amount of milliseconds to have a fully rendered layout will be, again, bigger!
Beside, if the image will be cached it won't be downloaded for every other page where other cells in the sprite are necessary. As summary, sprites have pros and cons, if we put every image present in the CSS inside a single sprite but the user is interested only into one page, we are probably wasting bandwidth, and the initial feeling will be a slow website. The good compromise is obtained grouping related images inside a single sprite, being sure that if one is required, the rest of the UI will use at least 2/3 of other images in the same sprite.
JavaScript And Sprites Rule
Even if precedent point could sound obvious, we generally act in the opposite way with JavaScript. Not every library has been created to load incrementally and jQuery, as example, is one of these libraries. Even if we use just Sizzle and few core methods, we usually include the full library.
OK, jQuery is lightweight by default, and I have used it as example for its popularity, but it is a good example to explain that JavaScript is usually served as just one file with everything inside, but this is not the best we can do ... remember sprites rule? Only if we use at least 2/3 of the library in that page it makes sense to include the entire library ...
Other libraries such MooTools, YUI, or dojo allow us to choose the exact package we need for our purpose or, even better, these libraries are able to load dependencies incrementally and run-time ... is this always a better technique?
Well, from parallel download point of view it is, but for overall responsiveness it may be not the right way.
Try to imagine a page with 6 files/namespaces dependencies, if these 6 files would have been served in a single one, minified and gzipped, a single request with a better/shared compressed dictionary would have been better than 6 different files. Still Sprites Rule: for few more milliseconds but a single request and a better compression ratio, the overall responsiveness of the page will be improved, thanks to every included dependency, rather than split files and lazy requests.
In other words, if without those files the page is not usable, the user will have a bad or "slow" experience, compared with the page that uses those files loading them in a shot.
The ideal scenario would be a non-blocking lightweight loader on the top able to call grouped or optimized piece of a library and execute code only at the end, something like this:
JAVASCRIPT:
-
(function(){
-
function script(src){
-
// create the script tag and load it
-
var script = d.createElement("script");
-
script.type = "text/javascript";
-
script.onload = script.onerror = onload;
-
script.src = src;
-
head.insertBefore(
-
script,
-
head.firstChild
-
);
-
};
-
function onload(){
-
// code already parsed, remove this script
-
this.parentNode.removeChild(this);
-
// call the callback, if present
-
// when every script has been loaded
-
if(--length == 0)
-
$.onload()
-
;
-
};
-
var // document shortcut
-
d = document,
-
// the head element or the documentElement (quirks)
-
head = (
-
d.getElementsByTagName("head")[0] ||
-
d.documentElement
-
),
-
// scripts length
-
length = 0,
-
// exposed object
-
$ = {
-
// method to call to load scripts
-
load:function(){
-
for(var
-
i = 0,
-
l = length = arguments.length;
-
i <l; ++i
-
)
-
script(arguments[i])
-
;
-
// chain to add an optional onload
-
return $
-
},
-
// silly dual behavior for every taste
-
// this.onload = function(){}
-
// or
-
// this.onload(function(){})
-
onload:function(onload){
-
$.onload = onload;
-
}
-
}
-
;
-
return $;
-
})()
-
// calling load function ...
-
.load(
-
// one or more file
-
// order not guaranteed (parallel downloads)
-
// suitable for namespaced libs
-
// or totally unrelated files
-
'http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js'
-
)
-
// adding an onload callback ...
-
.onload(function(){
-
// jQuery is here
-
// be sure page has been loaded
-
$(function(){
-
alert($('body').html());
-
})
-
})
-
;
Above is just a 420 bytes (265 deflated) example function but fortunately every library able to load incrementally will have a better and more powerful one. Is the suggestion/idea clear?
JavaScript And Evaluated Comments
On slide 16 we can learn about the last amazing technique which aim is to speed up the whole parsing and executing process. I am talking about JavaScript in comments, totally ignored, unless conditionals, from every JavaScript engine, not parsed at all and for this reason faster to include as part of the code. but for some reason faster to evaluate. To be honest, I have not studied internals yet and to me is quite obscure the reason a function call, as eval is, should be that faster than native included code, since the parser will pass the code in any case and the latter one needs to be executed. The only guess I have is that eval misses something compared to native parsing, but I don't know what ... Sure is that via Firefox and enabled Firebug or analogue debuggers, eval will be slower, due to overload caused by the debugger itself, so may I suggest Function(strippedComment)() instead?
Global scope as a native included code will have, and less stress for debuggers!
OK, I went to far with Function suggestion, and my point over this comments technique is that being necessary to retrieve the comment content, as part of the text contained in the script, we cannot gzip/deflate the code unless the entire page has been compressed.
Being the network round trip one of the most costly operations for a mobile device, I don't think this is a universally valid technique for desktop browsers. Parallel downloads are almost a joke for today mobile phones, but hopefully a reality for common ADSL or fiber optic connections.
As best option for both scenarios I think the evaluated code in a string one is more than reasonable since it can be easily included as external file and it can be handled via namespaces.
JAVASCRIPT:
-
var myLib = {
-
/*generic library*/
-
util:{}
-
};
-
-
(function($nmsp){
-
-
// a generic namespace loader
-
myLib.namespaceLoader = function(nmsp){
-
if(!$nmsp[nmsp]){
-
$nmsp[nmsp] = true;
-
eval(myLib[nmsp]);
-
}
-
};
-
-
})({});
-
-
// code apparently faster to evaluate
-
myLib.myLib_util_alert = "myLib.util.alert=function(s){alert(s)}";
-
-
// load the required namespace
-
myLib.namespaceLoader("myLib_util_alert");
-
-
// try the namespace
-
myLib.util.alert("BOOH!");
Well, the whole point is about network round trip, isn't it? At least we know that if we have a dynamic layout but a static script, hopefully based on ETag and caching solutions, above suggestion will make sense as valid alternative.
CSS And Sprites Rule
Following for the last time the Stripes logic, CSS are rarely loaded incrementally. One call? Same style sheet for the whole website? Well, it could be a valid reason to serve a single file but at least we should remove noise from our CSS. How? It is simple, split the CSS for targeted browsers.
In the recent Confessions of a style sheet hacker, Jason Garrison justifies the usage of hacks for a single browser: Internet Explorer 6.
How many hacks are necessary to let this browser behave like every other? Unless our layout is not truly simple, lots of them! If we put "noise" inside a CSS specific for every browser but IE6, every browser will load unnecessary styles, slowing down the parser with messed selectors, and adding bytes, improving used bandwidth and download time as well.
Jason already replied and I would like to thanks him, but I still think an extra call for a single case is more worth it than overall noise for everyone.
My Performances Contribution
What a good occasion to introduce my latest project which aim is to improve performances for every static client file to serve?
PHP Client Booster aim is to use some good practice to improve 2 times or more client file serving. A common mistake with PHP website is the one to use
PHP:
-
// don't stress your server with this
-
even for static libaries, CSS, recently suggested to serve @font-face compatible fonts ... but this could be a complete waste of resources over performances reductions, rather than improvements, specially if produced generic output could have been pre-compressed.
Compatible with every static file, serving a 304 as soon as possible, including only necessary code, and compatible with load balanced environments as well thanks to a shareable ETag management, PHP Client Builder is a cross-platform tool able to pre-compress resources, serving as default file type a deflated version, optionally a gzipped one, and finally the raw version of the original file.
The reason I have chose deflate as default file serving is that it does not overload the compressed file with initial extra bytes and it may be slightly faster with inflate against gunzip.
Moreover, some old browser had problems with gzip and its extra bytes but it should not have problems with deflate. The tool, which needs lot of documentation I am planning to write, should not be obtrusive, it could be customized or added in our already present Framework/environment, and it comes with a bench/ folder for a "try yourself" purpose. Comments, suggestions, or questions, will be appreciated (for the whole post as well).
Thursday, October 22nd, 2009
Category: Performance
Frederico Caldeira Knabben of CKEditor fame has replied to some of the comments to the CKEditor 3 article with a post about the load time performance of CKEditor 3.
He starts out by showing the perf that he gets from Poland:

As you can see, the entire sample weight is 105KB, loaded and rendered in only 2.67s. Of course, different countries and connections will give different results, but considering that I'm way far from Chicago those are amazing results.
The key for amazing download performance is not related to the size of the stuff we're downloading, but instead the number of downloaded files. We kept a strong focus on this fact during the development of CKEditor and, as we can check above, the entire editor is loaded and is ready to use with only 7 files being downloaded. We can even reduce this number, but here we're talking about the default editor distribution, with no additional performance hacks. That's really amazing, compared to the 13 files we needed to download for each FCKeditor instance in the page (more details later in the article).
Just to give an example, still using the above Firebug results, note that the 81KB of the ckeditor.js file is loaded in only 1.2s, while the combined 24KB of the other 9 files is loaded in 1.5s.
He later talks about some optimizations:
There are a few optimizations that could be done to reduce the number of files being downloaded by CKEditor:
- If you need the editor interface to be localized in a single language only, you can set the language configuration option to that language code, and simply copy the contents of the language file (localized in the "lang" folder) at the very end of the ckeditor.js file. This will avoid this file being downloaded.
- It's recommendable to set the editor configurations in-page, instead of using the config.js file. Other than making it easier to upgrade the editor, you can even avoid downloading that file, by simply setting customConfig to an empty string ('').
- Standard configurations can be overridden by simply setting them into the CKEDITOR.config object directly, at the end of the ckeditor.js file, or even in-page, right after loading the editor file.
By doing the above optimizations, the editor download is reduced to only 5 files.
Monday, October 19th, 2009
Category: Debugging, Performance
Steve Souders has posted about the HTTP Archive Specification and how it is now supported by both Firebug and HttpWatch (and hopefully more soon!).
Steve says it best, and it started as his baby, so I will let him announce it:
What’s needed is an industry standard for archiving HTTP information. The first step in establishing that industry standard took place today with the announcement of HttpWatch and Firebug joint support of the HTTP Archive format.
HttpWatch has long supported exporting HTTP information. That’s one of the many reasons why it’s the packet sniffer I use almost exclusively. Earlier this year, as part of the Firebug Working Group, I heard that Firebug wanted to add an export capability for Net Panel. I suggested that, rather than create yet another proprietary format, Firebug team up with HttpWatch to develop a common format, and drive that forward as a proposal for an industry standard. I introduced Simon Perkins (HttpWatch) and Jan “Honza” Odvarko (main Net Panel developer), then stepped back as they worked together to produce today’s announcement.
The HTTP Archive format (HAR for short - that was my contribution ;-) is in JSON format. You can see it in action in HttpWatch 6.2, released today. HAR has been available in Firebug for a month or so. You need Firebug 1.5 alpha v26 or later and Honza’s NetExport add-on (v0.7b5 or later).
Here’s what the end-to-end workflow looks like. After installing NetExport, the “Export” button is added to Firebug Net Panel. Selecting this, I can save the HTTP information for my Google flowers search to a file called “google-flowers.har”.

After saving the file, it’s automatically displayed in Honza’s HTTP Archive Viewer web page:

I can then open the file in HttpWatch:

I’m incredibly excited to see this milestone reached, thanks to the work of Honza and Simon. I encourage other vendors and projects to add support for HAR files. The benefits aren’t limited to performance analysis. Having a format for sharing HTTP data across tools and browsers is powerful for debugging and testing, as well. One more block added to the web performance foundation. Thank you HttpWatch and Firebug!
Wednesday, October 14th, 2009
Category: CSS, Performance

Our favorite ex-Yahoo at-Google web performance fast-driving all-around guru Steve Souders took a look at @font-face performance recently:
There have been a number of great posts about @font-face performance issues:
* Paul Irish: Fighting the @font-face FOUT
* Stoyan Stefanov: Gzip your @font-face files
* Zoltan Hawryluk (again): More @font-face fun
This blog post summarizes Paul, Stoyan, and Zoltan’s findings plus some very important discoveries of my own.
Among these discoveries is:
* IE doesn’t render anything in the page until the font file is done downloading.
* In all major browsers, ...no files were blocked [by font downloads].
* Busy indicators... are triggered [differently in each] browser
Steve also found that IE and Chrome didn't time out in their attempts to download a font, meaning in the case of the former that the page never displays while waiting for the font, and in the latter that the text doesn't display.
Steve's conclusions are interesting:
* Only use @font-face is you’re absolutely certain you need it.
* If you have multiple font files, consider sharding them across multiple domains.
* Don’t include unused @font-face declarations - IE will download them whether they’re used or not.
* Gzip the font files and give them a future Expires header.
* Consider lazy loading the font files, at least in IE.
Next Page »