rakaz

about standards, webdesign, usability and open source

Make your pages load faster by combining and compressing javascript and css files

As some of you may know, I am currently working on a content management system. Although I am not able to share all of the code – it is proprietary after all – I already made one debugging tool public. This tool can be used to test some common techniques which decreases the bandwidth generated by feed consumers. Today I am going to make a second tool public – including source code. It is a method to decrease the loading time of a page by combining all the different css or javascript files and compress them.

About six months ago I noticed the pages generated by the content management system were in itself very clean and small, but that these pages still took a long time to load for new visitors. Even on a fast internet connection it took more than 8 seconds to load a basically empty page. The server generated the page in about 350ms, so that wasn’t the problem. The problem turned out to be a combination of two things: each page used more than 12 different css files because each plugin supplied its own css definitions and because the use of the rather large prototype and scriptaculous javascript libraries which also consists of a couple of different files. Now that an article about the same problem featured on the Yahoo! User Interface blog, I decided to make my solution public, so others can benefit from it.

The solution turned out the be simple, combine all the different files into a single large file and compress that file using gzip. Unfortunately, if you do this manually you are going to run into maintenance problems. That single compressed file is no longer editable. So after editing one of the original source files you will have to recombine it with the other files and re-compress it.

Instead of going for the easy – but hard to maintain – solution I decided to automate the process and thanks to a small PHP script and some clever URL rewriting I now have an easy to maintain method to speed up the loading of pages that use many or large css and javascript files.

The idea is that you have one directory for css files and one directory for javascript files on your server. If you rewrite the URLs that point to these directories to a small script that intercepts the requests for those files. The script loads the file from disk and compresses it using gzip. It then sends that compressed file back to the browser. Given that javascript and css files compress really well this will greatly decrease the size of the data that is going to be transferred and thus decrease the time needed to download these files. Because this works completely transparently you do not need to change anything in your existing code.

But there is more. Compressing the files will decrease the size of the data that needs to be transferred, it does not solve the problem that the browser can only download a limited number of files at the same time. If you have many different files that need to be loaded the browser will not optimally use the bandwidth it has access to. It will request some files from the server and wait until those files are retrieved before the rest of the files are requested. The solution to this problem is to combine all those different files into one large file. And this is exactly what the script tries to do. You can concatenate different files by simply adding the names of the other files to the URL of the first file.

Take for example the following URLs:
http://www.creatype.nl/javascript/prototype.js
http://www.creatype.nl/javascript/builder.js
http://www.creatype.nl/javascript/effects.js
http://www.creatype.nl/javascript/dragdrop.js
http://www.creatype.nl/javascript/slider.js

You can combine all these files to a single file by simply changing the URL to:
http://www.creatype.nl/javascript/prototype.js,builder.js,effects.js,dragdrop.js,slider.js

The script will intercept the attempt to retrieve something from the javascript directory and will notice that you want to fetch multiple files at once. It will then concatenate the requested files, compress it and send it as one to the browser. Also notice that I include the files that come with scriptaculous manually and I do not use the scriptaculous.js file like you normally would. The reason for this is that scriptaculous.js loads each javascript file individually. If I use the scriptaculous.js file I will get the benefit of compression, but the different files won’t be combined into a single file.

Unfortunately I noticed a nasty side effect of the combination of these two methods. If you combine many files the resulting files can be come quite large. Compressing those files takes some time and on a busy server that time will become large enough to negate a significant portion of the improvements you made earlier. But this problem can also be solved by simply adding a cache that stores an already combined and compressed version of the files. The cached version is automatically created the first time that particular combination of files is used and used every time – as long as the files are not changed. The result is that once the cache is created there is almost no overhead and the compressed file is delivered almost instantly.

I’ve done some informal testing on my own website and I did get some impressive results. Before this script was added to my website you needed to download 8 javascript files, in total 168 Kb – the prototype and scriptaculous libraries. On average this took about 1905 ms. After installing this script you now need to download only a single file of 37 Kb which only takes around 400 ms. Your results may vary of course, but given that it shaved 1.5 seconds of a total loading time of 3.5 seconds, this script almost cut the time needed to load a page on my weblog in two.

Configurating this script is easy. First you need to download and configure the combine.php script. By default this script look in the javascript and css directory in the root of your website, but if you are currently using different directories you can change these values at the top of the combine.php script. Upload the combine.php script to the root of your website. Secondly you need to create a cache directory that is writable by the web server. Again, by default this script will look for the cache directory in the root of the website, but you can change this in the combine.php script. Finally you need to create or modify your .htaccess file. If you do not have a .htaccess file you can create it in the root of your website and add the following lines. If you already have an preexisting .htaccess file you can simply add the following lines to the file:

RewriteEngine On
RewriteBase /
RewriteRule ^css/(.*\.css) /combine.php?type=css&files=$1
RewriteRule ^javascript/(.*\.js) /combine.php?type=javascript&files=$1

Note: if your preexisting .htaccess file already uses URL rewriting you do not need to add the first two lines. You can simply add the last two lines to the bottom of the .htaccess file.

121 Responses to “Make your pages load faster by combining and compressing javascript and css files”

  1. Joost de Valk wrote on December 18th, 2006 at 5:21 pm

    Cool, very cool indeed, will be using this on numerous sites :)

  2. Lim Chee Aun wrote on December 18th, 2006 at 9:33 pm

    Wow, this is really great! If I’m not mistaken, the files can be compressed further right if let’s say, remove all new lines and tab characters? Though I supposed it might make the file unreadable to some curious people…

  3. rakaz wrote on December 19th, 2006 at 4:16 am

    Hi Lim Chee Aun,

    You could let the script pass the javascript through a javascript packer such as JSMIN or the PHP version of Dean Edwards packer. I’m not sure if it will matter very much, because gzip encoding already compressed quite good. Perhaps it will shave of an addition Kb or two.

  4. Nathan Logan wrote on December 19th, 2006 at 5:40 pm

    Impressive. Great execution on a great idea.

  5. Ralph Dagza wrote on December 19th, 2006 at 8:57 pm

    congratulations

    i saw your site listed on 9rules

  6. Ryan Breen wrote on December 20th, 2006 at 9:05 am

    Great article. To answer an above question — you could certainly pass the code through a text mangler, and a combination of the two will give you your best performance. In general, though, you will get your biggest gains from the compression Niels describes in this article.

    Niels, I would like to create a head-to-head benchmark between the before and after with this technique. I think it would be cool to get hard numbers to demonstrate the power of this approach. Does that sound interesting to you?

  7. alex wrote on December 20th, 2006 at 9:19 am

    this looks like a great solution. i’m just trying to test it, but i can’t figure out where the script is looking for the cache folder — you say that it’s in the root directory by default, but i don’t see where i can change that. a clarification would be greatly appreciated.
    all best,
    alex

  8. rakaz wrote on December 20th, 2006 at 9:43 am

    Ryan Breen: It should be easy to add an additional javascript packer to the script. Could be done in two or three lines of code. One problem you could run into is the compatibility between the packer and the actual javascript. I know that prototype and scriptalicious have are known to cause problems for some packers.

    alex: It looks like I accidentally replaced the latest version with an older version. I’ll update it as quickly as possible. The correct version is 0.3

  9. rakaz wrote on December 20th, 2006 at 9:49 am

    alex: Fixed.

  10. Markus wrote on December 20th, 2006 at 10:01 am

    Is it secure in that it is not possible to fetch files directly (like *.php) which otherwise wouldn’t be accessible?

  11. rakaz wrote on December 20th, 2006 at 10:11 am

    Markus: Hmm… I guess there might be a small problem right now. The .htaccess file makes sure that only urls that end with .js or .css are intercepted by the script, but it is possible to combine the php file with a css or js file to circumvent this restriction.

    I do check if it tries to access files outside of the specified directories and stop those attempts. Only if you include php files in the same directory as javascript and css files you could have a security problem.

    I’ll update the script to add an additional check to make sure that only .css and .js files can be combined. That would solve all problems.

  12. rakaz wrote on December 20th, 2006 at 10:18 am

    Markus: Fixed in 0.4

  13. alex wrote on December 20th, 2006 at 11:21 am

    thanks a lot, rakaz. works like a charm.

  14. Jason Grigsby wrote on December 20th, 2006 at 11:22 am

    Was there some reason you couldn’t use mod_gzip or an equivalent package for your web server?

    You really should use *something* that looks for the http encoding header coming from the browser to indicate what types of encryption the browser supports.

    That’s the nice thing about using mod_gzip or some of the other library packages. They are built to look for the http header. They also do a good job handling the exception to the http header (NS4 reports to support gzip, but really doesn’t).

    Using mod_gzip would not combine the files so you would still have the http connection overhead of the multiple files, but on the flip side, you’d also be gzipping all of your content without having to maintain your own gzipping scrip.

  15. feki wrote on December 20th, 2006 at 1:37 pm

    Hi!

    Great stuff! Thank you!

    I would like to use it from a subdirectory.
    How can I do that?

    RewriteRule ^templates/web2/css/(.*\.css) /includes/combine.php?type=css&files=$1
    RewriteRule ^templates/web2/javascript/(.*\.js) /includes/combine.php?type=javascript&files=$1

    Thank you everything!

  16. rakaz wrote on December 20th, 2006 at 1:54 pm

    feki: Ok, it seems like you have the following directory structure:
    /templates/web2/css/
    /templates/web2/javascript/
    and you want to place the combine.php script into:
    /includes/

    This means that you need to use the following rewrite rules:
    RewriteRule ^templates/web2/css/(.*\.css) /includes/combine.php?type=css&files=$1
    RewriteRule ^templates/web2/javascript/(.*\.js) /includes/combine.php?type=javascript&files=$1

    You need to configure the combine.php script like this:
    $cssdir = dirname(__FILE__) . '../templates/web2/css';
    $jsdir = dirname(__FILE__) . '../templates/web2/javascript';

    I don’t know where you placed the cache directory, but by editing the $cachedir variable in the combine.php script you can determine it in the same way as the javascript and css directory

  17. Ivan wrote on December 20th, 2006 at 7:01 pm

    I remember reading that IE is having problems with gzipped javascript/css files, it won’t cache them..
    did you test how nice your script plays with IE cache ?

    If files are not cached, it’s a major flow, since you end up serving your files on every page load, instead just the first-time..not just that it’s slower, but server load goes up, too..

  18. Markus Geiger wrote on December 21st, 2006 at 9:13 am

    Nice script. I did the same some time ago. The project uses yui and yui-ext witch resultet in >600KB of javascript. Now it uses 90KB compressed in one file, and since use of a browsercache site-switching is now instant site switching ;)

    Good to see you also implemented the HTTP 304/ETag – many people forget that in their caching scripts!

  19. amzani wrote on December 21st, 2006 at 5:25 pm

    good,
    I am also working on a content management système, i used Packer JavaScript to compress all my javascript(scriptactulous + prototype..)…but i have a problème with Safari
    Your solution is better , it’s a better idea to combine CSS too.i will test that…

  20. Hady wrote on December 22nd, 2006 at 7:46 am

    Great script rakaz. Like it a lot and will implement it in my website. I have been developing this web app that uses yui and yui-ext and prototype and scriptaculous and was starting to scratch my head when seeing the deteriorating loading time at the bottom of my browser.

    I might extends this script by packing javascript and css files first. Will share the code once I get it done.

  21. Morten wrote on December 22nd, 2006 at 11:05 pm

    Why don’t you just enable server compression? The browser reports if it accepts compressed data, and the server will automatically compress it before transport. That way you don’t even need to bother with zipping your javascript and, better, you don’t need to check if your script is working or worry with bug/security fixes.

  22. rakaz wrote on December 23rd, 2006 at 2:40 am

    Morten, Jason Grigsby: Compression is just one element of what this script does. If you only need compression than mod_gzip would be fine. This script also combines multiple files into one which reduces the number of required http connections.

  23. Philip Withnall wrote on December 24th, 2006 at 10:00 am

    Brilliant, as always! Works a charm. :)

  24. Manish Mittal wrote on December 26th, 2006 at 8:54 am

    Hi,

    I did few changes in the script so it works with multiple folders.

    Changes in combine.php
    $path_parts=pathinfo($_SERVER[REQUEST_URI]);
    $cache = true;
    $cachedir = $DOCUMENT_ROOT . ‘/cache’;
    $cssdir = $DOCUMENT_ROOT . $path_parts['dirname'];
    $jsdir = $DOCUMENT_ROOT . $path_parts['dirname'];

    .htaccess file
    RewriteEngine on
    RewriteRule ^JS/(.*\.js) gzipscript.php?type=javascript&files=$1
    RewriteRule ^script/JS/(.*\.js) gzipscript.php?type=javascript&files=$1
    RewriteRule ^JS/(.*\.css) gzipscript.php?type=css&files=$1

  25. Manish Mittal wrote on December 26th, 2006 at 9:34 am

    Hi,

    I did few changes in the script so it works with multiple folders.

    Changes in combine.php
    $path_parts=pathinfo($_SERVER[REQUEST_URI]);
    $cache = true;
    $cachedir = $DOCUMENT_ROOT . ‘/cache’;
    $cssdir = $DOCUMENT_ROOT . $path_parts['dirname'];
    $jsdir = $DOCUMENT_ROOT . $path_parts['dirname'];

    .htaccess file
    RewriteEngine on
    RewriteRule ^JS/(.*\.js) gzipscript.php?type=javascript&files=$1
    RewriteRule ^script/JS/(.*\.js) gzipscript.php?type=javascript&files=$1
    RewriteRule ^JS/(.*\.css) gzipscript.php?type=css&files=$1

  26. Matthew wrote on December 26th, 2006 at 3:40 pm

    Great script! While looking into why it wasn’t working for me, I found out that my server does not support HTTP_IF_NONE_MATCH, which is needed in order for the caching to work. I’m now trying to figure out how to get it enabled on the server. If I find out, I’ll post it here to help anyone else in the same situation. If anyone has any suggestions too, I’d appreciate them.

  27. Thomas wrote on December 28th, 2006 at 10:27 am

    I remember using gzip on our servers a couple of months ago. It ran smoothly for a couple of weeks until some strange behaviour starting showing on some of our users computers.
    It seemed that some versions of Internet Explorer didn’t like all the gzipping to much.
    I would really like to use it but if it doesn’t work 100% on the most used browser it’s worthless to me…
    If you know anyting about these problems, could you contact me at
    thomas D.o.t. vandierendonck a.t. gmail d.o.t. com

    tnx

  28. Joe wrote on December 29th, 2006 at 3:46 pm

    Rakaz, AWSMOME
    Manish, With the changes you suggest, what does the calling url look like? Have you tested it?

  29. pbhj wrote on December 30th, 2006 at 3:14 pm

    Have you tested side by side against hosting server gzip compression to see what the difference is?

  30. pHoEniX wrote on December 31st, 2006 at 5:29 am

    Hi Rakaz. Thanks, this sounds amazing, I am going to try this on my website.
    I also read the comments above, and I just want to ask about HTTP_IF_NONE_MATCH and this IE thing is solved already? Many thanks.

  31. Gaurav Adesara wrote on January 9th, 2007 at 8:54 am

    Hi , this is really nice one,
    may i know that how to load fast web site in PHP symfony framwork .My site is not loading fast even file size are also small.

  32. weevilgenius wrote on January 10th, 2007 at 4:44 pm

    One potential problem I’ve found is that the encoding type is not included in the cache file name, so it’s possible for a browser newly visiting the site to be served up a cached file with an encoding that it doesn’t support. Unlikely, but possible. Great work so far!

  33. Ahmad wrote on January 23rd, 2007 at 7:47 am

    Is there an ASP version of the script?

  34. Carlton wrote on January 26th, 2007 at 4:00 am

    Can I ask what tool you use to measure the page rendering time? Was it Firebug, the mozilla firefox extension?

  35. YOHI wrote on January 27th, 2007 at 2:14 am

    hi

    i read above article on how to make faster pages .it lis a great idea.. please keep posting like those innovative idea.
    instead of using .htacess, it tried this , it is working..

    thanks
    yohi

  36. MarkB wrote on February 9th, 2007 at 2:10 pm

    :(

    I’ve tried to no avail to get this working. I know its due to my missing something along the way, but I’m hoping you’ll be able to provide me with some assistance.

    I’m using wordpress and thus I’m a little hazy as to the file structure etc that I should be using in my htaccess and combine files.

    This is my current (non-working) configuration:

    htaccess:
    RewriteRule ^wp-content/themes/fpf/(.*\.css) /combine.php?type=css&files=$1
    RewriteRule ^wp-content/themes/fpf/js/(.*\.js) /combine.php?type=javascript&files=$1

    **the combine.php file is in the root of my site, so ie in the same place as the htaccess file, not in the root of my theme…

    combine file:
    $cachedir = $_SERVER['DOCUMENT_ROOT']. ‘/wp-content/cache’;
    $cssdir = $_SERVER['DOCUMENT_ROOT']. ‘/wp-content/themes/fpf’;
    $jsdir = $_SERVER['DOCUMENT_ROOT']. ‘/wp-content/themes/fpf/js’;

    is this all correct?
    i’m hoping you say ‘no’, because these settings dont work. the page loads fast, but my scripts don’t work at all.. :(

    Hoping to hear from you soon.

  37. jojje wrote on February 19th, 2007 at 7:28 am

    nice work!

  38. Alex wrote on February 22nd, 2007 at 12:04 pm

    I do have problems when the style or script files are updated. Although the combined file is regenerated it is not loaded. The pages shows up without javascript and css. I then have to reload the page and it works again.

    Any ideas what I am doing wrong?

  39. fugazer wrote on March 11th, 2007 at 4:47 pm

    i cant get this to work either.. im using joomla

  40. Walt Mecleary wrote on March 31st, 2007 at 10:19 am

    I got it working. Well it’s creating cached files in the folder I specified.
    How can I tell if my hosting server is sending the cached css and .js?
    When I go weboptimiztion test site, the optimizer is loading the full scripts and not the cached ones, I think???

    And yes gzip really makes those files small. A 40k css is compressed to 8k. WOW!!!
    Just by finding this thread, it really made me rethink my home page. I got the HTTP requests down from 41 to 20. That was a huge improvement in speed, the combining of .js into one line technique is a great idea. Instead of six HTTP requests I use just one. BIG IMPROVEMENT

    Is there anyway to test what files the server is outputing? cached or non-cached?

    Sorry to pose question here, but I couldn’t find a forum or anywhere else to post;)

  41. Anthony Ettinger wrote on April 5th, 2007 at 1:45 am

    Very clever :)

  42. Christo Crampton wrote on April 12th, 2007 at 3:31 am

    Would this script work on files hosted externally? for example YUI files hosted on the Yahoo! servers?

  43. Leonidas Tsementzis wrote on April 12th, 2007 at 10:21 am

    Great one! Thanks

  44. TeeCee :o) wrote on April 12th, 2007 at 1:34 pm

    Thank you!
    I made a self-made-portal-engine optimalisation, and I pack/strip and cache all my JS and CSS files, but load them separately. This one will be a step forward, great idea!

  45. Waleed Zuberi wrote on April 13th, 2007 at 8:47 am

    Great article! Very useful technique you’ve taught us. Read about it in the SitePoint Tech Times.

  46. Joe Pecoraro wrote on April 13th, 2007 at 6:36 pm

    I think its a great script and I am going to to try to use it right now. I also want to point out that you did an excellent job describing the situation and what you did to solve the problems. Great article, I think it will work great for me.

    I also want to point out that the link to the download shows a php file (version 0.5) that does not end in ‘?>’ an easy fix for any reader,just a heads up.

  47. www.artweb-design.de wrote on April 13th, 2007 at 7:14 pm

    Rails plugin: Blazing fast page loads through bundled CSS and Javascript: I recieved an interesting Sitepoint newsletter the other day which talked about bundling CSS and Javascript ressources (or “assets” like that’s called in Rails talk) to achieve faster page loads. This caught my attention specifically because I experienced the need to repackage many small CSS files on the fly a while back when I worked on a large CMS-type system. Skimming through the PHP source …

  48. Joshua Brewer wrote on April 16th, 2007 at 12:14 pm

    So would this work on PHP includes as well? Would that speed up the load process?

  49. Ozh wrote on April 17th, 2007 at 3:32 pm

    That’s really smart, thank you for this. I particularly like the way you’re dealing with cache and encoding or not.

    I’ve added a timer to echo a comment at the end of the generated file to see what’s the server side impact, I’m a little suspicious about all these file calls (fopen, file_exists and so on)

  50. Ozh wrote on April 17th, 2007 at 3:49 pm

    Another note (sorry for spamming):

    testing on PHP_OS could avoid the round of testing for 404 (line 60 of your script) since realpath already checks for file existence. Works fine except on BSD (or at least I’ve been told so)

  51. Alexei wrote on April 18th, 2007 at 3:31 am

    This is great, but (I feel so dumb) it doesn’t work at my site :(

    This is my .htaccess, and it works fine:


    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /main.php [L]

    .htaccess for combine.php works fine too:


    RewriteEngine On
    RewriteBase /
    RewriteRule ^css/(.*\.css) /combine.php?type=css&files=$1
    RewriteRule ^javascript/(.*\.js) /combine.php?type=javascript&files=$1

    But combined in any way, they make a mess.

    I tried at first like this:


    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /main.php [L]
    RewriteRule ^css/(.*\.css) /combine.php?type=css&files=$1
    RewriteRule ^javascript/(.*\.js) /combine.php?type=javascript&files=$1

    And after that in every order, but nothing.

    So, there’s the question – what do I have to put in my .htaccess to make both redirections work? What am I misssing? Please help.

  52. Carsten Schwede wrote on April 18th, 2007 at 3:36 pm

    Dammit… works great… but now get’s me thinking about switching from mootools to YUI/EXTJS…

    Thx alot for point out that solution!

  53. Ethan wrote on April 20th, 2007 at 12:26 am

    This is a really amazing solution Niels. Unfortunately I can’t get it to work on a site I’m working on.

    In a directory named ‘includes’ I have a file, ‘header.php’, which contains the HTML that links to my stylesheets.

    In the root directory I have these files…

    .htaccess (copied from above)
    combine.php
    index.php

    …along with other pages. index.php ‘includes’ header.php. When I load the page, none of my stylesheets work – just unstyled HTML. I tried to view the css with Firebug, and it said that there are no rules in my stylesheet.

    I know that I can use URL rewriting because I use it with wordpress.

    If you have an idea, please lend a hand.

    Ethan

  54. Darick wrote on May 1st, 2007 at 12:00 pm

    I ported the code to C# and ASP.Net. It cab be found at Code Project.com

  55. Till wrote on May 8th, 2007 at 10:07 am

    Hello Niels,

    this is an awesome script with a really clever train of thought! – Keep up your great work. :-)

    I’ve one question resp. suggestion:

    Would it be possible to delete the old unused files in the cache folder after the new ones were generated by Combine 0.5? – Especially during development and test phase of website programming accrue a lot of files in the cache folder. But only a handful (only the actual ones) of them are required.

    The PHP script checks first if there were a modification in the included css or javascript files resp. if the files in the cache folder are up to date. If not, Combine generates the new cache file(s) and stores them additionally (!) in the cache folder. But the old files remain there. (After 1 week of development I have above 200 unnecessary cache files.)

    Where do I have to implement a “Delete Old/Unused /Unnecessary Cache Files”-function?
    How could this function look like in order to make sure that only the old files are deleted?

    I would be pleased about each suggestion.

    TIA!

  56. AsGoodAsItGets wrote on May 9th, 2007 at 7:32 am

    Hi, very nice script indeed but I just noticed that my IE6 (SP2) is never served the gzipped version.

    Upon inspection I found that on line 100 (version 0.5) you are checking for the presence of “EV1″ in the user-agent string and if it fails, then you use no encoding.

    I assume your intention was to check for the presence of a Service Pack indicated by “SV1″ or “SV2″?

    In this case this line is wrong.

    Am I missing something?

  57. Avi wrote on May 10th, 2007 at 5:31 pm

    i am on a shared hosting account, and i am trying to set this up. However I am having some problems. Just to clearify, I have the lines added to my .htaccess file
    RewriteEngine On
    RewriteRule ^css/(.*\.css) combine.php?type=css&files=$1
    RewriteRule ^js/(.*\.js) combine.php?type=javascript&files=$1

    the combine.php file is located int the same directory the .htaccess file is located. If i use firebug to look at the css or js files, it says “loading” under response and never finishes. The js and css files never do load as no styles appear on the website.

  58. Hellion wrote on May 11th, 2007 at 4:30 pm

    it’s a great script!
    Thanks!

  59. joomlaprodigy wrote on May 24th, 2007 at 2:08 pm

    I have installed it and can see a gzip file for both the combined javascript ans css. however my question is why it still loads the uncompressed file for both css and javascript. I checked the file size that is downloaded using IBM Page detailer. Ans even weboptimizer tool in FF shows the file downloded is the uncompressed one.

  60. Mark Thien wrote on May 30th, 2007 at 12:24 am

    Great job ! This is COOL…..AWESOME …..!! I once had this slow loading problem and I so stupid that I took out all the javascript and include/exclude it page by page. i am using OpenSymphony Sitemash framework with appfuse 1.9.4.

  61. Jason Litka wrote on May 31st, 2007 at 10:11 pm

    Nice code. I’m using this on a project I’ve been working on. It dropped the load times from about 1.6-1.7 seconds to 0.8-0.9 seconds.

  62. Sascha wrote on June 17th, 2007 at 6:18 am

    This is amazing! I just lost about 50% of my loading time on several projects! ;)

    Thanks for this input.

  63. George wrote on June 20th, 2007 at 7:10 am

    Great script started using it on my forums but have one issue. Before i had mod_expires set up to cache js files in visitor’s browser cache for


    ExpiresActive On
    ExpiresByType application/x-javascript A172800
    ExpiresByType text/css A86400

    but now with the combined js script, the js files are loaded each page load which seems slightly slower pulling from /cache directory than if it’s already in my browser’s cache (visitors) even if the file size is smaller 8kb for 2 js files versus 50kb + 19k for 2 js files.

  64. DG wrote on June 20th, 2007 at 6:53 pm

    rakaz,

    First of thanks for the nice solution. I’m using this PHP trick on WordPress 2.2. There’re few query’s that I want to clear from you:

    1. In WordPress 2.2 onwards prototype.js, scriptaculous.js etc javascriptsare bundled and are in /blog/wp-includes/js/ folder.

    2. There’re many plugins too that bundle there own js files, for e.g. livesearch.js.

    The js bundled with plugins resides in /blog/wp-content/plugins/plugin name folder.

    3. Apart from the above, I’ve few other javascripts, that I’ve copied into root and I’m able to compress these javascript files.

    However, I’m not able to make to compress javascripts that resides in as mentioned in step 1 and 2 above.

    CSS:

    1. My CSS files are mostly in /blog/wp-content/themes/Connections/

    2. Other than these, some plugins do use their own CSS files and those resides in their own folder i.e. /blog/wp-content/plugins/plugin name.

    My query and the help that I want from you is “how do I combine or add multiple path in combine.php and .htaccess to get the compression done.

    Please advice.

    Regards,
    DG…
    http://www.ditii.com

  65. JohneeMac wrote on June 25th, 2007 at 5:04 am

    How do you go about testing the speed of the file loads? Is there a FireFox extension? I have FasterFox but it doesnt give you individual file load speeds….Thanks.

  66. Philip Arndt wrote on July 4th, 2007 at 7:28 am

    JohneeMac use Firebug
    https://addons.mozilla.org/en-US/firefox/addon/1843
    (use the ‘Net’ tab)

  67. Sascha Postner wrote on July 7th, 2007 at 1:52 pm

    I too have a question. Although I use this solution and think it is brilliant, I wonder if it is possible to also combine css and js files that are important inside conditional comments?

    I guess this would/should result in different caches for different “combinations” of css files (e.g.). Becaus in some browsers you would have e.g. 2 css files and in the ie maybe 3.

    Does this work?

  68. defunc.com wrote on July 16th, 2007 at 7:35 am

    Faster Pages—Bundle CSS & Javascript: For any large site or any high volume site, it is really important to remember to keep the number of server requests to a minimum. And with more and more css, .js libraries and extra’s being added to your site, it doesn’t take long till you are in need of some size stripping. In doing [...]

  69. dmlinn.com wrote on August 9th, 2007 at 12:31 am

    Combine and compress your CSS and Java: So you have your site running on the latest and greatest Java libraries, but your supporting CSS and JavaScript files are really starting to slow things down. You’re no JavaScript expert, so what do you do? Lucky for us some other people have already encountered this problem and have a great solution. Make your pages load faster by combining and compressing javascript and css files The site its…

  70. weblabor.hu wrote on August 9th, 2007 at 5:18 pm

    Mit is kezdjünk a CSSeinkel?: Hogyan oldjuk meg CSS fájljaink szervezését.

  71. Adam Messinger wrote on September 2nd, 2007 at 1:16 pm

    Thanks for this script. I’m using it on an in-development site for a client, and it’s cut 40 KB of JavaScript in four files down to 17 KB in one file. Page loads are noticeably faster now.

    There’s one small issue with the rewrite rules that you might want to address. putting a forward slash in front of ‘combine.php’ overrides anything that’s been set using RewriteBase. If this script is being used from a sub-directory, it will appear to fail regardless of whether RewriteBase has the correct directory name.

    To fix this problem, just remove the forward slash that comes before ‘combine.php’ in the rewrite rules. If RewriteBase is left at its default of ‘/’ then those forward slashes are unnecessary, anyway.

  72. chris wrote on September 20th, 2007 at 1:59 pm

    So with this what I would do is leave all of the javascript and css files where they reside but just copy them to their own folders in the root directory, as long as I change combine.php file? The idea is that they get predownloaded into the cache, correct?

  73. kerasin95 wrote on November 9th, 2007 at 10:46 am

    If this script is being used from a sub-directory, it will appear to fail regardless of whether RewriteBase has the correct directory name. Compression is just one element of what this script does. If you only need compression than mod_gzip would be fine.

  74. Milos wrote on November 12th, 2007 at 7:46 pm

    Yes that´s really awesome! I didn´t know some issues before. So i like your article very much – it helps me on some way to speed up some things on my projects sites. Thank you for sharing your exp. and knowledge with us all!

    Greetings from Regensburg, Germany

  75. Brian wrote on November 15th, 2007 at 10:34 am

    The idea is that they get predownloaded into the cache, correct?
    Thanks for information.

  76. Philippe Bolduc wrote on November 15th, 2007 at 3:41 pm

    Great script but i found that it’s make return empty page from apache when used with ssl. Does anybody know why. I seem to be cause by the Etag header ??

  77. Chris wrote on November 16th, 2007 at 5:33 pm

    Hi,
    could someone pls. let me have a hint howto let apache serve .css compressed without starting any on-the-fly scripts – somthing like .css.gz

    Would be great to get any response!

    Greetings,
    Chris

  78. Torkil wrote on November 22nd, 2007 at 10:48 am

    How does the caching work? Does it clear the cache every now and then? Is the cache cleaning interval maybe configurable too?

  79. Amir wrote on November 24th, 2007 at 8:04 pm

    Really nice thing. A few issues I had to handle:
    * Scripts / css in different folders (you can email me at arakaz at aweawe dot cjb.net for my source).
    * gzip encoding gave me problems since PHP already gzips all my PHP scripts. When setting $encoding = ‘none’; it should be fine.
    * The line: header (“Content-Length: ” . filesize($cachedir . ‘/’ . $cachefile)); gave me trouble. The file was downloaded but then the browser would still wait for timeout. It’s probably because I didn’t use gzip with the script but (as I wrote before) with my apache/PHP settings.

  80. Josh Fraser wrote on January 9th, 2008 at 7:34 pm

    Great script. I wrote a garbage collector to remove old files from the cache. To add this to your version, simply add this code at the bottom of combine.php under “Store cache”.

    // garbage collector deletes old version from cache
    $dh = opendir($cachedir);
    while (false !== ($filename = readdir($dh))) {
    if ($filename == ‘.’ || $filename == ‘..’)
    continue;
    if (strpos($filename,”-”.$md5_file_list) && $filename != $cachefile)
    unlink($cachedir.’/’.$filename);
    }

  81. habrahabr.ru wrote on February 6th, 2008 at 10:57 pm

    06.02.2008 21:57:31 aleks_raiden: спасибо, буду завтра пробовать.

  82. Schmappel wrote on February 7th, 2008 at 3:24 pm

    Great technique, thank you for sharing this!

  83. Kroc Camen wrote on February 11th, 2008 at 4:13 pm

    I know yours is a set-it-and-forget-it system, but I also managed to crack this problem using a build system for a js-heavy web-project I created, and that does something similar by combining and compressing scripts together, but not expending server CPU power on every request.

    It’s taking 20 js files down to just 2, with a saving of about 70% filesize.

    Check my URL for the project website

  84. Il Fabbro wrote on February 14th, 2008 at 4:29 pm

    Nice script, but is there a way to automatically read out a dir for css-files, so you don’t have to call on each file separately? I.e. when I add a CSS-file to my CSS-dir, I don’t want to add it manually to the link-line.

  85. Joey wrote on February 19th, 2008 at 10:19 pm

    This is nice. But how on earth do you load the Scriptaculous files individually because:

    /js/&files=scriptaculous.js?load=effects

    is obviously not working

  86. Mael wrote on February 22nd, 2008 at 3:02 pm

    What a fucking great idea!
    I had to modify the script a little bit for my windows devellopement server. I also changed rules into

    RewriteRule ^(.*)/(.*\.js) libs/combine.php?type=javascript&dir=$1&files=$2

    to be able using differents directories.

    Thank you for sharing!!!

  87. weblabor.hu wrote on February 26th, 2008 at 12:36 am

    CSS and JavaScript build process: Fejlesztői környezetből könnyen gyorstárazható CSS és JS fájlok előállítása

  88. www.jaisenmathai.com wrote on February 27th, 2008 at 10:05 am

    Speed up Apache – how I went from F to A in YSlow: I decided to embark on figuring out how to make my site as fast as possible. There were a few tips I was already aware of but decided to grade myself using YSlow . My initial score was bad, an F. I realized I had to do a few things. Compress text/* files using gzip Decrease HTTP requests by combining multiple JavaScript (and CSS) files into single files Add aggressive caching since the site isn…

  89. www.xpro.su wrote on February 28th, 2008 at 4:47 pm

    Объединение JavaScript и CSS-файлов для ускорения загрузки: Когда страница использует большое количество внешних JavaScript-файлов или скриптов CSS (а такое часто бывает, если используются библиотеки типа Prototype или jQuery), время ее загрузки существенно растет, так как каждый такой файл — это новое обращение к серверу, т.е. трата нескольких сотен миллисекунд. Но тем не менее, есть способ избежать эту проблему: воспользоваться серверным скриптом, кот…

  90. Jonny wrote on February 29th, 2008 at 8:51 am

    Hm, this looks good, but for some reason i cant get it to work. It seems that when the cache file is being read, it isnt be decoded. I view the “response” through firebug, and it’s all jibberish. Anyone know hwo to get around that?

  91. alex wrote on April 16th, 2008 at 4:39 pm

    how do i combine css and js files?. My root .htaccess is blocking it. It does n’t understand multiple css in the request.

    # Turn on the Rewrite Engine
    Options +FollowSymLinks
    RewriteEngine On

    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    RewriteCond $1 !^(index\.php|system|img|css|js|video_files|robots\.txt|favicon\.ico) [NC]
    RewriteRule ^(.*)$ index.php?/$1 [L]

  92. Ikaro wrote on May 7th, 2008 at 11:22 am

    Great hint. Thanks

  93. Cosmin wrote on June 13th, 2008 at 12:04 pm

    i dont know what is the problem , but localy on my wampserver is working but on a shared host it doesnt load the css and the javascript and i saw that it hangs at :

    line 70 : if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) == ‘”‘ . $hash . ‘”‘)

    everitime the “then” cause is executed and it returns nothing.
    why? any help?

  94. Marc Falk wrote on June 27th, 2008 at 8:00 pm

    Hi,

    Thanks for the great script.

    How do I implement it? It doesn’t work so far…
    Should I include it in my header or?

    Thanks in advance!

    Marc

  95. Greg wrote on August 9th, 2008 at 9:47 am

    I like this script but any idea of how i could group files having different paths like javascript/prototype.js,xyz/builder.js with xyz being a subfolder of the javascript folder.
    I welcome a way to make it work

  96. Prabath Peiris wrote on August 12th, 2008 at 8:40 pm

    Hi
    I have the same issue. build a site but its tooooo show in IE. This method might help me, but I try to follow the instruction given but its little bit unclear to me. okay … this is what I did I copy combine.php file in to my root directory and update javascript and css files directories in the fine. and create a .htaccess file and copy those instruction in to that (change the java and css dir names in it too). include combine.php in my index.php file. and then ……. what is the next step.

    Thank you very much
    Prabath

  97. AlexM wrote on August 17th, 2008 at 2:55 am

    Your blog is interesting!

    Keep up the good work!

  98. Jeff wrote on August 17th, 2008 at 10:15 am

    My site is setup like:
    /ess (external css)
    /java (short for javascript)

    has /cache installed in the root and set to 777

    and has the combine.php modified with above info and uploaded in the root.

    But nothing is being written into the cache after a bunch of page loads. Shouldn’t that be happening?

  99. Ap wrote on August 26th, 2008 at 12:06 am

    Thanks, great script! Do you think it could also optionally include site images for even better performance?

  100. Ap wrote on August 29th, 2008 at 12:21 am

    I’ve added some code at line 132 to remove tabs & newlines from css files, thus making it a weeny bit faster (depending on the size of your css file of course).

    // strip tabs & newlines of css
    $pattern = str_split("\t\n\r\0\x0B");
    $contents = ($type == 'css') ? str_replace($pattern, '', $contents) : $contents;

    I’d like it to be a little bit smarter by stripping all spaces except those within : & ; and by omitting comment blocks, but for now at least it’s a little gain :)

    Thanks again!

  101. niaher wrote on August 29th, 2008 at 6:42 am

    This is a really really amazing idea. Thanks a lot for sharing it. I’m definitely implementing this on my site.

  102. www.t-six.com wrote on September 10th, 2008 at 10:50 am

    Make Pages Load Faster (Web Dev): About six months ago I noticed the pages generated by the content management system were in itself very clean and small, but that these pages still took a long time to load for new visitors. Even on a fast internet connection it took more than 8 seconds to load a basically empty page. The server…

  103. www.vbulletin.com wrote on September 21st, 2008 at 5:12 pm

    Styles Optimization of javascript / CSS: vBulletin loads 8+ external Javascript files, ranging from 1 to 30+ KB. Neither of them is gzipped or minified (cached?), and this requires 8 separate HTTP requests from clients to the server to render a page. Considering the fact many browsers are limited to 4 simultaneous HTTP requests at a time, and the added server load for each separate connection, reducing the number of requests for .js f…

  104. sandeepkonstant.wordpress.com wrote on October 10th, 2008 at 9:45 am

    Make your pages load faster: rakaz – Make your pages load faster by combining and compressing javascript and css files Make your pages load faster by combining and compressing javascript and css files       

  105. www.supertopic.de wrote on October 14th, 2008 at 10:45 am

    JS/CSS Online Kompressor gesucht: Helau everybody, ich suche einen Onlineservice (wenn es denn sowas schon gibt), der mir mehrere JS-Files zu einer zusammenzippt. Zum Beispiel jQueryCore+5 jQuery-Plugins+1 selbstgeschriebenes File in eine handliche Datei. Am besten wärs natürlich, ich gebe nur eine URL an und die ballern dann alles schön raus, ähnlich wie das Smush it! macht Ziel ist es die HTTPRequests zu minimieren und die Da…

  106. H.kagan Gungor wrote on October 27th, 2008 at 11:40 am

    Hi, just became curious… whats goin on – on my site.

    well, I’ve uploaded files (both .htaccess and combine.php) and my site became more faster.
    but, as I created a folder called “cache” – has no contain any files.?

    What would reason for this situation. It has also write access…

    let me give the files/folders/htaccess content.
    includes/css
    includes/jscript
    includes/themes

    directories:
    $cssdir = dirname(__FILE__) . ‘/includes/css’;
    $themesdir = dirname(__FILE__) . ‘/includes/themes’;
    $jsdir = dirname (__FILE__) . ‘/includes/jscripts’;

    .htacess file is like
    RewriteRule ^css/(.*\.css) /combine.php?type=css&files=$1
    RewriteRule ^jscripts/(.*\.js) /combine.php?type=jscripts&files=$1

    could you please whats the reason?

  107. paul wrote on November 3rd, 2008 at 9:37 pm

    Hi Rakaz,
    this seems like a perfect solution for me, but my code is very complicated , and i have js in at least 10 directories
    and css in at least 10 directories

    how do i alter the script to deal with so many directories

  108. tutorialajax.com wrote on November 7th, 2008 at 7:45 pm

    Compress JavaScript with Gzip: The main problem when we are using ajax framework is because of their big size. Of course, it will extremely slow down the sites load time. For example, if we use the standard jQuery , it’s almost 100Kb. It’s even more if we use the complete Prototype and Scriptaculous that will cost around 150Kb. This is really nightmare for people who still use GPRS or the old 56kbps Dial-Up internet connecti…

  109. Neil wrote on November 9th, 2008 at 4:21 pm

    Nice, very nice.

    I have a build script that automates minifying during the build process for the netbeans IDE(see my blog for details).

    I am in the design stage for a netbeans plugin that will also combine and minify js files.

  110. www.imfreakz.com wrote on November 15th, 2008 at 5:06 pm

    How to make our Busby Page have faster load times?: JavaScript (JS) can provide functionality and interactivity to a web site, but the main benefits are server resource conservation because of their big size. This make us want to make our Busby SEO Test Page site have better loading time and void to use javascript. If we want to use it we will try to use less JS. For an example we use only one JS in this busby seo page. It’s only light JS, so it…

  111. Remodev wrote on December 14th, 2008 at 4:16 pm

    Helo all,
    im using Zendframework and the folowing .access to redirect all request to my bootstrap file (index.php)

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ – [NC,L]
    RewriteRule ^.*$ /index.php [NC,L]
    RewriteRule ^css/(.*\.css) /combine.php?type=css&files=$1
    RewriteRule ^javascript/(.*\.js) /combine.php?type=javascript&files=$1
    and the javascript files and css files are not loading
    so can you tell me what’s wrong in my .access
    my directory structure is as folow
    /index.php
    /combine.php
    /javascript
    /css

    thx in advance!

  112. Deeg wrote on December 22nd, 2008 at 4:20 pm

    This is great. Can you think of a way to do this any requests to the server? Like all the images?

  113. cuocthiseo wrote on January 4th, 2009 at 5:40 pm

    Great advice, now my visitors can save lot of time when they surf my website, and live on my site longer, many benefits.
    Thanks for share.

  114. Phil Campbell wrote on January 4th, 2009 at 5:57 pm

    This looks awesome. One question thou, i have my css files and js hosted on s3 (also using cloudfront) do you think i would gain anything from using this as well and will it support external sites?

  115. Karim wrote on January 15th, 2009 at 11:08 pm

    Great script.. it works like a charm..

    One question though, do you see anything wrong with doing
    http://www.creatype.nl/combine.php?type=javascript&files=prototype.js, builder.js,effects.js, dragdrop.js,slider.js

    instead of :

    http://www.creatype.nl/javascript/prototype.js, builder.js,effects.js, dragdrop.js,slider.js

    The first one does not require the rewrite rule, so works fine on my windows dev station… And I thought why not use the same on my prod (linux)

    Thanks a lot for this script

    Karim

  116. Speed Dating wrote on January 27th, 2009 at 1:58 am

    Speed dating says: I really like the code that you have written. I am having trouble making a page written in old HTML load faster. I am wondering if there is software that can automatically recreate the HTML into XHTML with a CSS file too. Your solution can help me cause it compresses things, but the site divisions in the page I am working on is divided by tables instead of division tags.

  117. gdenarayana wrote on February 12th, 2009 at 5:47 pm

    woahh…great tutorial, i came from search engine to see a neat JS tutorial and i’ve got here :)

    thanks and best wishes to you ;)

  118. Lim Choon Hong wrote on February 18th, 2009 at 4:54 am

    Hi, will this affect the search engine crawler when they crawl your site?

    Thanks

  119. Gerben Oosterink wrote on March 2nd, 2009 at 11:36 am

    this really works perfectly, but when using IE6 it doesn’t work. The files are not gzipped, is this a known issue?

  120. Hectic Capiznon Bloggers 2009 wrote on March 3rd, 2009 at 9:26 am

    thanks for sharing this article..

    more power..

  121. www.geektechnica.com wrote on April 20th, 2009 at 11:37 pm

    7 Optimization Tips For WordPress: When we first sat down to start designing this site we had one priority over everything else. Speed . Not only do we hate slow loading websites, we believe in simplistic designs and are crazy about optimizing websites to the extreme. Though  most of these tips can be applied for any websites, we will be focusing on wordpress tips. What is a good page loading time? Before we start optimizing the…