When it comes to front-end performance, good asset management is just as important as good code. Simply put: downloading assets takes time.
Computers and browsers now render pages and execute Javascript faster than ever. Although user bandwidth is increasing, the filesize of assets has been growing in turn.
These factors, combined with the rise of the mobile web, have made bandwidth the primary bottleneck in website performance.
Here are 5 simple steps to reduce download times with better asset management on your sites:
1. Limit HTTP Requests
One of the easiest ways to improve asset management is to reduce HTTP requests.
When an image, stylesheet, JavaScript or web page is requested, your server has to do a bit of work to lookup and serve that file. So it’s a good idea to limit the number of these requests as much as possible.
- Replace multiple images with image sprites
- Merge JavaScripts into a single file
- Merge stylesheets into a single file
- Combine Ajax requests
2. Compress Assets
JavaScript / CSS compression is basically minifying to the extreme: it removes extra whitespace and renames local variables to be as short as possible. This ensures that your JavaScript and CSS files stay compact, and makes a dramatic difference in filesize over non-minified code (especially if you use 4 spaces per tab like I do).
For compression, try YUI Compressor or Packer.
Images should also be compressed, either using standard JPEG/PNG compression, or Adobe’s Save for Web dialog.
Finally, if you’re really concerned about performance, minify HTML as well.
3. Gzip Everything
Gzipping assets is just about the best thing since sliced VPS.
Gzip drastically reduces filesizes, leaving gzipped assets at around 40% the size of their unzipped counterparts. Although browsers take a small performance hit when decompressing these files, the overall result is a huge performance increase caused by significantly shorter download times.
Gzip is also very versatile: it can be used a variety of ways for all HTML, CSS and Javascript assets.
For experienced pros, gzipping can be achieved very easily using .htaccess. However let’s walk through some simpler techniques for the rest of us.
First, gzipping HTML is a piece of cake using PHP. Simply include this snippet at the top of any PHP page:
<?php ob_start("ob_gzhandler"); ?>
Just make sure to call this before any HTML output, and your PHP will serve gzipped HTML.
Next let’s do something similar for our CSS assets:
<?php
ob_start ("ob_gzhandler");
header("Content-type: text/css; charset: UTF-8");
?>
and our JavaScript assets:
<?php
ob_start ("ob_gzhandler");
header("Content-type: text/javascript; charset: UTF-8");
?>
Put these snippets at the top of your CSS / JavaScript files, but bear in mind that Apache will need to view these as PHP files. The easiest way to accomplish this is to change the extension, e.g. site.css
becomes site-css.php
.
While linking to site-css.php
works just fine in a or
tag, there are a variety of reasons to opt for the native
css
extension rather than php
. If the extension matters, use a quick rewrite in .htaccess:
RewriteRule ^css/site.css$ /css/site-css.php
4. Set Cache Expirations
Some browsers won’t cache assets whose cache expirations aren’t set. So it’s a good idea to set expirations in the future for any assets you want cached by browsers.
Conversely, if there’s an asset that you don’t want cached, simply set its expiration in the past.
However, setting cache expirations can be a bit tricky. Since they are controlled via HTTP headers, you’ll need a way to manipulate these. On any Apache server, this can be done via .htaccess, but this might be a bit difficult for .htaccess beginners.
Alternately, HTTP headers are easy to set if you use an asset delivery service such as Amazon S3 (which I highly recommend for a variety of reasons). With Amazon S3, there are a variety of tools you can use to easily set HTTP headers, such as S3 Hub for Mac and S3 Browser for Windows.
Finally, HTTP headers can be set via PHP, but this will only help with JS / CSS assets, and not images. This is a big drawback since images usually benefit the most from cache expiration headers: they are used more frequently and tend to be more static than JS/CSS files.
5. Use a Cookie-less Domain
Cookies fatten the filesize of every asset you serve, and just like with real cookies, it’s an issue of quantity. Even a few hundred bytes of cookies becomes a big deal when you consider that they’re downloaded with every single asset.
So it’s a good idea to serve all your CSS, JavaScript, Flash and image assets from a static server that doesn’t use cookies.
One way to handle this is to use a separate subdomain for static assets. However you’ll need to be careful to set cookies with “www.yourdomain.com” instead of the default “.yourdomain.com”, which is inherited by all subdomains.
However if you’re like me and don’t use the www subdomain, you’re out of luck for using a cookieless domain. One way to get around this is purchasing a separate domain for static files, like yourdomainassets.com.
But if you’d rather not spend money on domain registration, there’s also a free option. 2static.it provides a free cookie-less subdomain that can link to a (sub)domain of your choice. The only downside with this service is the lack of branding: although you can set a subdomain name, you’ll have to be OK with users seeing 2static.it as the root domain for all your assets.
Zipper photo credit: Idle Type, Download icon credit: Studiomx
great suggestions! i’ll try these out immediately!
thanks,
-johnny
You should also think about using Google AJAX Library API if your site uses a popular JavaScript libraries such as jQuery, jQuery UI or MooTools offering a number of benefits. Google host these libraries and can be linked to for free. This saves you bandwidth, serves up the scripts on a CDN, and has great caching benefits. If a website you previously visited used Google AJAX library to serve jQuery 1.4 for example and your site does the same, when that user visits your site they do not need to download the jQuery library as it will already be accessible from their browsers cache.
Great article. I’ve always been interested in creating a separate sub-domain to serve assets. I will take your findings under consideration and implement them in the very near future. Thanks for the insights.
Thanks for a lucidly written tutorial. Going to try the suggestions listed, hopefully should see better performance with these fixes.
Its a pity that PHP can not set Expires headers for images.
good stuff mate 🙂 another nice article.
thanks
I didn’t know about gziping. does it bother SEO?
otherwise – i’m right on it.
Wow, A must read & implement article. I have applied all the 5 tips on my site. Thanks a ton.
BTW, here is a small writeup on GZipping CSS, JS etc that I wrote a while ago: http://viralpatel.net/blogs/2009/02/compress-php-css-js-javascript-optimize-website-performance.html
Thanks
Hi Jon,
For point #3, we have a free service that allows for easy checking for gzip of assets on any site. Maybe you would find it useful to include it in the article: http://gzipwtf.com
Actually we just checked this very page and it looks like you could turn on gzip for your css files!
gzipWTF