Though we live in an age where a lot of people have fast internet connections. The focus (at least for developers) has shifted to technologies that relieve the server of heavy workloads and increase processing speeds such as AJAX, using server-side and client-side caching, as well as gzipping. In this post I will lightly touch upon client-side caching of dynamically generated CSS and JavaScript files.
I recently installed YSlow, a handy web development tool for Firefox. In it there is an option that tells you whether your CSS or JavaScript files are cached on the client’s computer allowing for a quicker page load. I noticed my files were not cached so I looked a little into how to go about caching them so the browser won’t download the same file over and over when going from page to page. So I went about conducting my own tests to see how to make this happen. The only way of making it happen other than setting an expire date/time on the WHOLE page (or on the .htaccess file in Linux servers) was to create a server-side file that would output the expiration, content type headers as well as the actual styles/code in your web application. Below is a clearer picture of how I made it happen.
PHP- Step 1.
Make a dynamically generated CSS file that includes expiration and content headers (code below). Save it as ‘dynamic_css.php’. The actual CSS styling can be typed in the same way you would do in a regular stylesheet, we are only after getting those expiration and content type headers sent out.
<?php
header("Expires: Thu, 31 Dec 2020 20:00:00 GMT");
header('Content-type: text/css');
?>
h1 { color: Red; }
PHP- Step 2.
Add ‘dynamic_css.php’ as the CSS href of you document. This should make YSlow happy and increase the speed at which the user navigates through pages that use the same CSS file. Use the same method to add expiration tags to JavaScript.
<link rel="stylesheet" type="text/css" href="dynamic_css.php"/>
ASP- Step 1.
The way I added expire tags to my CSS code in ASP is very similar to PHP’s. First you make a server-side CSS file and save it as ‘dynamic_css.aspx’. Since it is important the headers hit the server first we use server-side code to send those out first. We type in the actual CSS code like we would in a regular CSS file after that. Besides would you really want to Response.Write() all of your CSS code? I think not.
<%
Response.Expires = 3600
Response.ContentType = "text/css"
%>
h1 { color: Blue; }
ASP- Step 2.
Add ‘dynamic_css.aspx’ as the CSS source of you document. This should make YSlow happy since the expiration headers are now being sent increasing the speed at which the user navigates through the pages that share the same CSS file. Use this same header method to add expiration tags to JavaScript files.
<link rel="stylesheet" type="text/css" href="dynamic_css.aspx"/>


January 27th, 2009 at 5:30 PM
Great! Thank you very much!
I always wanted to write in my site something like that. Can I take part of your post to my blog?
Of course, I will add backlink?
Sincerely, Your Reader
January 30th, 2009 at 9:42 PM
Of course!
February 5th, 2009 at 4:36 PM
Hi. Your site displays incorrectly in Opera, but content excellent! Thanks for your wise words:)
March 28th, 2009 at 4:13 PM
I purchased an eCart that has many xxx.css.php files and added your step 1 tip to the top of the page and that worked to exclude them from being reloaded.
I run YSlow and get the add expires message for existing ???.css and ???.js files. Could you provide a little more detail on how to fix these, I’m not much of a coder so if you could show the code on a page that would help a lot.
Thanks in advance
April 1st, 2009 at 8:42 PM
Hey Cy,
I have not tried to add expire headers to actual css and js files yet. The way I describe on this article to go about doing it is change your js and css files into a php file and add the header there. I have found a link that might answer your question. Try it out and let me know. I might write a post on it later on.
http://www.askapache.com/htaccess/apache-speed-expires.html
February 15th, 2010 at 1:38 PM
quite interesting post. I would love to follow you on twitter.