YSlow Optimization Part 2 – Expire Headers, Compression, CSS and Javascript

Happy Friday and welcome to Part 2 in my series on YSlow Optimization. In this installment we are going to discuss the benefits of implementing expire headers, using proper compression and how to effectively include CSS and javascript files. The methods I will go over today are not the only way to accomplish these tasks but are what I personally feel to be an effective way to do so. I will break this post down into several sections to make it easier to follow and reference as you make the needed changes to your site.

Add an Expires or Cache Control Header

This is perhaps one of the single most important optimizations you can make that will both assist your server by reducing load as well as making your visitors experience while on your site more enjoyable, faster and in turn make them more likely to stay longer, visit more often and view more pages. I will start out with a brief explanation of the concept behind this and provide the solution that you can easily use for your own site, provided your server supports the methods I will outline here.

[youtube width=”250″ height=”175″]http://www.youtube.com/watch?v=OCAjmuA1HDk[/youtube]

When a visitor comes to your site for the first time their browser will request every piece of content that your site uses to make up whatever page they end up on, this can amount to a few Kilobytes or a possibly even a few Megabytes (or more if you get out of control) or content that your server has to send down the pipe to your visitors computer in order to display the page they are viewing. I’ll use an analogy here and hopefully it will make sense, if you are having a party and at this party you have a keg of beer and only 5 people show up because you are playing nothing but the Bee Gees and you smell funny it’s not a big deal if they grab a new glass when they come back to the keg for a refill, but what if you have 2500 people at your party and they all take a new glass every time they top off, wouldn’t it make a lot more sense for them to just keep the glass they have and use it again? After all they already have it and it is identical to all the other glasses sitting there. The same concept applies to your site, send them the content once, give their browser the information it needs to cache it so the next time they view your site, or another page on your site they don’t have to download the items they already have all over again, it really is just common sense were talking about here.

This rule can be broken down into two separate parts, one being to add far future expire headers to static components what don’t change and the other being to add proper cache control headers to dynamic content that may or will change. Understanding how your site is designed will make it easier for you to get the best results in your particular application. There is a very important consideration to make prior to doing this, you must remember that any content whether it be an image, css file, javascript or anything else that is cached will remain cached for the duration you specify no matter if you update the file or not. The only way to get around this would be to rename the file and edit any references to it each time you change the file so use this with caution as it would really suck if someone had your css file cached for 10 years and you make changes to your site that they will never see unless you rename your file. If you have followed my instructions in Part 1 of this series and are using PHP-Speedy now you don’t have to worry about this for CSS or javascript files as PHP-Speedy will generate and use a differently named file any time you update them, which is another very good reason to use PHP-Speedy.

Setting up expire headers is very easy, if you have access to your httpd.conf file you should use that, otherwise you can add the required information to the .htaccess file that is located in your sites root folder. I won’t blab too much as this will be pretty self explanatory, any extension you see listed here will be cached for the length of time specified. This is the code I am using on this site and it should work well for you as long as you remember that what I just said about the dangers of caching certain content for long periods of time.

[php]

<ifmodule mod_expires.c>
<filesmatch "\.(jpg|gif|jpeg|ico|swf|png|css|js)$">
ExpiresActive on
ExpiresDefault "access plus 1 year"
</filesmatch>
</ifmodule>
[/php]

That’s all there is to it, add that and your content will be held in cache by browsers that support it (read all good ones) for the period specified unless you rename the file. Now, moving on to the next step.

Compress Components with GZIP

A good analogy for this would be the exchanging of money, if you go into a store and spend $50.00 on something it makes sense to pay for that purchase with the smallest number of bills possible right? So it would be nice if you hand the cashier a single $50.00 bill and call it a day but if you aren’t able to pay with one bill, or generally like to be a jerk you can pay with with other methods, even with pennies and they have to accept it. The end result is the same, it just takes a lot longer to get to the end result and that cashier is likely going to want to beat you before you leave.

Using compression on your site is very similar, it will allow you to compress your content and send the least amount of data to your visitors computer as possible, when combined with proper caching this can lead to HUGE improvements in your websites performance with just a little added server load when you send the content to them the first time. Enabling compression is again a very easy task, as long as you are able to configure your server to do it or you are on a host that will allow you to do it. For GZIP compression to work it has to be enabled on your server, in Apache you will need mod_deflate and then you need to tell the server to compress your content, again this snippet should be added to your httpd.conf file if you can, or you can add it to your .htaccess file in your sites root folder. This is what I use on this site, your mileage may vary :-)

[php]AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/x-javascript application/x-httpd-php application/rss+xml application/atom_xml text/javascript[/php]

As you can see, I am pretty much compressing everything possible except images which are already compressed anyhow so that would be a waste. that’s it for this tidbit, add the code and save file, restart Apache if you added it to your httpd.conf file and you are good to go.

Put CSS At Top and Put Javascript At Bottom

This is by far the most self explanatory portion of this entire post, CSS files should be included in at the top of your site, in the head section and javascript files should be included at the bottom or in the footer of your site whenever possible. The reason for this are simple, you need CSS files in order for your page to render, giving your visitors browser this information as early in the game as possible will allow your content to be displayed as it becomes available or “progressively” which alone will give the impression that your page is loading faster.

Putting JavaScript at the bottom of the page whenever possible will have a big impact on the speed of your site as well, current HTTP specifications advise browsers to not download content using more than 2 parallel connections per hostname at one time, so this means you get 2 things happening at once per hostname which can be a huge bottle neck. By serving up content across multiple hostnames (more coming on this in later installments) you can get around this and speed up things greatly BUT if a javascript is being downloaded it will prevent all other connections until it is completely finished, this is why putting the javascript files at the bottom of your page is so important. You don’t want your page to sit blank while you are waiting for a script to load that adds your recent tweets to your footer do you? This is also handled almost completely by PHP-Speedy, so if you have that installed and working correctly you likely need to worry very little about this particular piece of instruction.

If you have any questions please feel free to post them here and I will assist you as best I can. Also, remember to come back by on Monday, July 27th for the next installment that will cover the YSlow areas on “Avoid CSS expressions, Make javascript and css external, Reduce DNS lookups, Remove duplicate javascript and CSS and Configuring entity tags (ETags). If you haven’t yet, please feel free to subscribe to my FEED to get notified when new posts are made.

<ifmodule mod_expires.c>
<filesmatch “\.(jpg|gif|jpeg|ico|swf|png|css|js)$”>
ExpiresActive on
ExpiresDefault “access plus 1 year”
</filesmatch>
</if

5 thoughts on “YSlow Optimization Part 2 – Expire Headers, Compression, CSS and Javascript”

  1. I always thought that javascripts were supposed to be placed in the section of a website? I know they don’t have to, in order to work, though.

    Well I might give it a go at another website of mine with a lot of javacsript etc. on it, see if it changes anything :)
    .-= Klaus @ TechPatio´s last blog ..Review: Joby Gorillapod =-.

    • Hi Klaus, thanks for stopping by. Many javascripts can be safely moved to the end of the page, some however will not work if they are.. A lot of it comes down to trial and error… this is definitely one of those things that takes some testing.

Comments are closed.