Pixelastic

You can cut our wings but we will always remember what it was like to fly.

Posts tagged with "performance"

Performance improvement : moving assets to subdomains

Disclaimer : What I'm talking about in this blog post can be optimised. Yes, having multiple hosts is a great feature for performance improvement, but I kind of did it wrong. My recent try at the webperf contest gave me more insight on how to do it right.

I'll post more on the subject or update this post to reflect that.

 

I've just added to this site a performance improvement I read a long time ago but never implemented.

I'm talking about the multiple domains to serve static content. There are two important things to note here : parallel requests and cookies. Let me explain in a little more details what it's all about.

Parallell requests

Your browser is only able to perform a certain number of parallel request at the same time. It means that it can only download a certain number of files concurrently (usually 4).

In other words, it will start the download of, say, a CSS file, a Javascript file, and two images. Then, whenever one of this files is received, it will start downloading a new file, and so on.

This means that there is a certain amount of time that is "lost" in the process. You have to wait for one of the files to be downloaded before starting downloading the next.

The important thing to note is that the limit on the number of parallel downloads is set on a per-domain basis. It means that you can download only 4 files of foo.com while downloading at the same time 4 files from bar.com. This is the basic of what we will be using to our advantage.

Splitting your files accross several domains (or subdomains) allows you to get the best of parallel download. You do not really need to have your content hosted on different servers, you just need them to be accessible through different domain names, and subdomains are just perfect for that.

I have created four subdomains : css.pixelastic.com, js.pixelastic.com, img.pixelastic.com and dl.pixelastic.com.

Each one maps to the exact same site as www.pixelastic.com but using different names improve the number of possible downloads and thus improve page load.

Cookies

All this stuff about subdomains brings me to my second point : cookies.

If you host all your files on the same domain, it means that all requests (be it a php page or a static css file) will send cookie information without you knowing.

Cookie data is usually small, like 100Ko or so, but is added to every single request made. And most of the time this information is not even useful.

Apart from the fact that you are slowly killing your website bandwith with useless information, your are also decreasing your page speed load for your potential user.

The same trick of using a subdomain applies here too, and cookies won't be sent.

There is one caveat that you should be aware of, though. If your site is accessible through domain.com and you host your files on files.domain.com, cookies will still be sent because domain.com is considered the master domain of files.domain.com and thus all cookies set on the main domain will also propagate to the subdomains.

On the other hand, if your main domain is www.domain.com, it is not considered a parent domain of files.domain.com (but rather a sibling domain).

Configuring Apache

If you need to edit your httpd.conf file, here is what I put to add my different subdomains on my local machine :

<VirtualHost *:80>
ServerName pixelastic
ServerAlias www.pixelastic
ServerAlias css.pixelastic
ServerAlias js.pixelastic
ServerAlias img.pixelastic
ServerAlias dl.pixelastic
DocumentRoot "www/pixelastic.com"
<Directory "www/pixelastic.com">
Options Indexes FollowSymLinks Includes ExecCGI
AllowOverride All
Order allow,deny
Allow from all
</Directory>
</VirtualHost>

 

CSS for Javascript enabled browsers

In a previous post I was wondering if my way of loading js-specific CSS rules was right. I was loading a specific css file for js overrides.

This allow for lighter stylesheets for users without Javascript (they won't load useless rules), but also resulted in slower rendering for other users because they needed to load two stylesheets instead of one.

After much pondering, I now think that loading all the rules in one stylesheet is the way to go.

In addition with the number of request mentionned, keeping all your rules in the same file is much more easier to maintain. Js-specific rules aren't that big either so the small additional bytes are usually better than a full http request.

I now prefix all my Javascript rules by .js. I add a js class to the html element directly from the head, this helps in preventing any FOUC that may occur because we add the class before the body rendering.

<head>
    <script>document.documentElement.className+=' js';</script>
</head>

 

How to hide/show elements based on Javascript

Sometimes you have a really great design with some really fancy Javascript goodness, like drag'n'drop and other shiny Ajaxy stuff.

But when you browse the website with Javascript disabled, none of that works and you end up with interface elements that should'nt be here because they do not work.

In those case, you'd rather display a nice message to your user, telling him that he can't use the feature withou Javascript enabled.

But how do you do that ?

Well, I myself load two different stylesheets. Remember that your website should be working without Javascript, this is just the last layer you add.

My default stylesheet will load all the rules for when Javascript is not enabled. No fancy cursor:move here.

Then I load a second stylesheet using Javascript, using document.write() in the <head>. And that's in this one that I write rules that overload the previous one. I add every styling that deals with Javascript-enabled features here.

Limitations

I may be changing the way I load the JS stylesheet in the future. I don't really like relying on document.write because it is evil. I also don't like the idea of getting one extra request.

I could add a js class to my body element (like modernizr does with all its CSS3 properties) and then target elements by prepending .js to the rule.

But it means adding rules in my main CSS file for users without JS that will still be downloading those extra useless bytes.

I haven't yet figured which way was the best (or should I say, the worst)

Convenient methodes

Whatever way you choose, one thing that really helped me was two real simple classes : jsOn and jsOff that I add to elements.

Elements with jsOn will only be visible if Javascript is enabled and hidden otherwise, while element with jsOff will do the opposite.

Assuming you mark your body element with a js class if Javascript is enabled, here's how to do it :

.jsOn { display:none; }
.js .jsOn { display:block; }
.jsOff { display:block;}
.js .jsOff { display:none; }

Hope all that helps at least someone.

Javascript speed tip : reduce variable lookup

It appears that, according to this video, when inside a Javascript function (or closure), if you want to access a variable, the closer your scope is to this variable, the faster you'll get it.

In simpler words, accessing a global variable (like document, or window) from inside a function will always be slower that accessing a locally defined variable.

It also means that, when inside a method of an object, accessing a variable defined in this method will be faster that accessing a property of the parent object, which itself will be faster that accessing a global variable.

So, for example, if you need to access at least twice a global variable like window or document in a method, you'd better cache it in a local variable first.

function myTestFunction() {
var button = document.getElementById('button');
var header = document.getElementById('header');
}

is bad and could be rewritten as :

function myTestFunction() {
var doc = document;
var button = doc.getElementById('button');
var header = doc.getElementById('header');
}

 

Meeting with Eric Daspet and Stoyan Stefanov in Paris

On July 21st will be held an informal meeting in Paris for all the web developers that have an interest in web performance.

Eric Daspet and Stoyan Stefanov will be there and host a talk about performance impact on sales and some more technical less known facts.

The first part will be in French while Stoyan's will be in English. If you have the chance to be in Paris in July, do not miss this event.

I will, of course, be there. Eric Daspet is the french "gourou" on web performances, and Stoyan Stefanov is one of the main author of the Smushit plugin/websit.

Web performance is a really interesting subject where there is so much to learn and so much to try.

Pros and cons of using Google CDN for your assets

With the recent Google Fonts breakout, much debate surfaces to know if it really was useful to use Google CDN to deliver your assets to your users.

I used to think it was a goog thing because it allowed for parallelized download, but after reading really good articles on the subject I'm not so sure.

I'll try to list the pros and cons of using Google CDN instead of serving your files locally.

Pros

  • Using a CDN assure you that your users will get content from the closest server around them, no matter where they are.
  • The more websites will use Google CDN, the biggest the chance of your user already having the file in its cache
  • Downloading from a CDN assure that you won't be sending useless cookies along the request. You shouldn't send cookies when fetching your static files anyway, but sometime -Google Analytics for example-, some script create domain-wide cookies that still get sent.
  • Many niched major websites (ArmorGames.com, StackOverflow.com, etc) uses the CDN, so if a large part of your trafic is coming from one of those, using the CDN and the exact same library version will have no perfomance downsides for you.

Cons

  • Using a CDN create a new connection to access the ressource on an other server instead of using the already open connection to your website. Creating a new connection is slow.
  • Caching of the files will only be possible if the exact same version url is used. E. using /jquery/1.4.0/ instead of /jquery/1.4/
  • If you already are using your own CDN for your images, you should also use it for your javascript and in this case the google one is worthless because you already have all the advantages.
  • An Internet connection is required. This may seem obvious but if you have to work on a project while on a trip, you'll need a local copy of the library.

Stalemate

  • Using a CDN force a DNS lookup. This lookup can be cached if the user already visited your website or another that use the same CDN however.
  • Browsers have a limit of paralels downloads on the same host. Using a CDN allow for more parallelization. But creating dummy subdomains like static.domain.com would also defeat this limitation.
  • In the case of Javascript/CSS, packing all your files (scripts and libraries) in one big file on your server and serving it gzipped will result in a better compression that serving the library from a CDN and your scripts from your server. On the other hand, the user would have to re-download the whole package whenever you make a tiny change to your scripts, even if you didn't changed the library.
  • Downloading script usually block page execution. So reducing the number of scripts to load (by packing them in one file instead of downloading one locally and one on the CDN) will reduce the blocking time. On the other hand, merging two files will result in a longer download time (because the file is larger) while using the CDN would allow the two scripts to download in parallel.
  • What happen if your CDN is down ? Well, when using Google that's not much a risk but still. As a side effect, you should'nt even consider using a CDN if your application is for an intranet.

Conclusion

As a conclusion, all I can answer to the "Should I use the Google CDN for my javascript libraries ?" is "Well... it depends...".

Really it depends on your configuration. Run some tests, try with a CDN or by compressing the library into your main file. Check where your users are coming from and the average loading time. Test various configuration until you found the one that works the best for you.

On a personal note I do use Google CDN for my websites. The cost of the DNS lookup and connection to the Google server is really worth the parallelized download in my case. But it may be so because I'm living in France and my website is hosted in the US, so a CDN really helps.

Source links

  • http://docs.google.com/document/pub?id=14Xn7kkKwVxSie6xHJwWRAP5mutM7qlWcrHgWtZo63gI
  • http://zoompf.com/blog/2010/01/should-you-use-javascript-library-cdns