Every day performance is becoming more important. Users expect websites to behave the same way as desktop applications in terms of speed and general performance. That’s why we, as developers, should make an effort to provide the best experience to our visitors.
This is a set of different techniques you can use to improve your website, depending on the area of optimization you want to target. If you are like me and enjoy improving sites performance you might find this list useful.
I pretend to keep this list as updated as possible. If you find mistakes or non-listed techniques, just let me know
I’d really appreciate your feedback.
Improve download time
Use a server near your user (or improving your RTT)
The fact of hosting your website geographically far from your target users can increase the round-trip delay time of your requests. Have a look at recent Mike Bailey’s article measuring RTT over a server in the USA and one in Australia. If you see yourself in this situation, consider changing your hosting server or using cloud servers such Amazon’s S3.
Reduce HTTP requests
Combination
By combining your requests you will improve your website load time. So instead of requesting 3 or 4 CSS files, try to combine them into one single file. The same applies to JS files. Personally I find useful to develop using multiple files and in a production stage combine them using a dynamic combiner. For instance an own function that minifies, combines and caches the output in the server.
CSS image sprites
As simple as merging several image files into a single one and use them from your css as background images, setting its position to the correct values.
CSS Data URIs
Instead of image sprites you can take a look at Data URIs. It can make you get rid off of big, non-mantainable images files. Just take into account that IE6 and IE7 don’t support this feature, and you should follow the MHTML workaround.
Multipart XHR
If the browser supports canvas (and javascript is enabled) it is possible to send several resources over the wire as a string formed by chunks of data concatenated, using a known string as a separator. Thus, in a single request reducing web traffic. The browser makes more work, having to split the data, but it is still a nice solution, improving load times in several magnitudes.
It is nicely explained on this video from Yahoo Developer Network where Ross Harmes (from minute 44) explains how Yahoo has planned to use it to the Flickr mobile version.
There are some caching (and IE) issues, but it may be useful for mobile sites targetting well known modern browsers.
Caching
Setting a cache strategy will make the browser don’t request again a file that has already downloaded. This is useful for static content that is not frequently changed or if we have implemented a system to serve newer versions of the file seemlessly (by last-modified or e-tag header, or by appending a version number to the query string). Or maybe it is just not a problem to have a client using a non-updated version of the file (in example, a body background).
Avoid 301 redirects
By linking consistently to correct URLs accross your website you will save the browser from requesting a URL, wait for a redirect message to finally request the right URL.
Reduce web traffic
Minifiation
Smaller files sizes can be achieved by minimizing content before sending it to the wire. Javascript and CSS files are well known to be easily minified (you can serve a minified copy of your file or let your server minify it on-the-air). HTML can also be minified by, for instance, removing white spaces (caution with the textareas).
LocalStorage versus cookies
I have already explained how localStorage can replace cookies for saving users’ preferences that the server doesn’t need to be aware of, reducing subsequently traffic.
Provide static resources from cookieless domains
If you just have to use cookies, try to isolate your static resources from cookie pollution. Thus you will reduce the size of your requests.
Split consistently static resources across different subdomains/domains
If you use different domains or subdomains to provide your static files, make sure that a client request a specific file always to the same domain, to take advantage of caching. This is important if files are simulated to be splited into different subdomains rather than really being hosted in different subdomains.
Images optimization
JPG and PNG files can be optimized using services like Yahoo’s Smush.it or jpegoptim. It may be not a huge save (after all, JPG files are supposed to be very optimized), but it is always good to keep your files as small as possible.
Gzip compression
This is a must. HTML, CSS and JS files should be gzipped. You can greatly reduce their size (at least the size of the file through the wire), and it’s very easy to be set up.
Compression using PNG, Canvas and getImageData()
Although it is a technique known since some time ago (see this Nihilogic article of 2008), during last days a series of tweets and posts have spread the word about this technique. In part, due to a post by ajaxian and the 10k application competition.
If the browser supports canvas (and javascript is enabled) it is possible to compress a file (css, javascript…) as a PNG image. PNG is a lossless image that seems to compress this files even further than gzip.
Last-modified and E-Tag
By using one of these headers, the server can respond to the browser that the version of the requested file is updated and does not need to download a new one. This is useful as a method to make sure every client uses the most updated version of your files. Just remember that a roundtrip is always neccesary to perform the check, so it might be not the best approach. You could consider adding a version string as a parameter in your URL requests.
Diffable
Google has just released a way to patch client files (mainly large JS files, but virtually any file) by just serving the content that has been changed from client’s version of the file to the current version.
Browser renderization
Putting Javascript includes after CSS:Javascript will block your CSS files due to the need of downloading and executing the file, before applying the CSS rules to the document. By putting javascript after CSS the browser can start to render the document sooner.
Non-blocking Javascript
There are different techniques to load Javascript without blocking the browser. Steve Souders made a great analysis of the different approaches and their support depending on the browser.
On-demand load
It consist of downloading javascript files as they are needed according to the user interaction.
Preload resources
It can be a good idea to download resources prior to when they are really needed if we know how they user usually behaves. For instance, in a paginated photo gallery you can stat requesting images that will be shown in the next page, to show the images to the user as fast as possible when page is changed. This has to be used carefully to not overload the browser’s memory and without damaging user experience when viewing the current page. A nice example can be seen on Facebook user’s albums, that provide json data containing the images urls, comments and tags of the photos of the album, saving requests to the server.
Early flushing
Steve Souders explains this technique to serve part of your document earlier, to allow the browser start requesting files before getting the full document.
Specify images dimensions
By setting the dimensions of our images we can help the browser find out the layout of the different elements of the documents, avoiding repaintings and reflows. This tip is nicely explained at Google Page Speed.
CDN
Using a Content Delivery Network can greatly improve the download time of your resources (as already stated before). Small websites can take advantage of CDN if they make use of Javascript libraries such as jQuery, requesting the framework Javascript files using a Google‘s or Microsoft‘s CDN. You can decrease your site traffic and improve the website load (maybe the user has already cached that file). Just consider a fallback in case there is any problem getting these files from the CDN.
Revise your javascript performance
Nicholas Zakas is great at showing javascript performance issues in his High Performance Javascript book. You can take a look to some of the tips, compiled by Jon Raasch.
Web workers
Web workers provide a way to execute javascript code in background threads. The goal is to perform processor-intensive calculations without blocking the user interface thread.
Others
Avoid 404 errors (pages and resources)
Always check that your links point to existing resources and pages. Make use of redirections if resources have been moved to a different URL. For example, Google Chrome requests favicon at path /favicon.ico when you have not set any favicon. This requests throws 404 errors. To avoid them, set a favicon, and in case it is not host in that path, provide a redirection to its path.
Thanks for reading! I will try to keep this list updated (at least for personal use) as more ways to make great performance sites appear.
EDIT (2 Sept. 2010) : Added “Compression using PNG, Canvas and getImageData()” and “Multipart HDR”