Consolidate CSS and JavaScript in WordPress
If you’re on WordPress and are using a lot of plugins, chances are that your blog is slower. No, not because of the plugins’ functions — that’s easily mitigated by WP-Cache — but because each of the plugins is inserting its own JavaScript and CSS into your blog. This causes users to have bigger page downloads and more HTTP requests, slowing everything down.
Note: This tutorial is for advanced users. Be careful! I screwed my blog’s commenting up for a while after posting this. :) I do not recommend messing with scriptaculous stuff — just leave it be. If you’re a novice, you probably don’t care about your site being a little bit slower, so this isn’t worth the effort.
Background
The best thing to do is to consolidate your CSS and JavaScript into singular files. This isn’t always possible — sometimes, the contents of included CSS and JavaScript depend on variables set in the plugins — but usually the included JavaScript and CSS are static.
Step 1: Find the culprits
Simply View Source on your site. Search in-page for “JavaScript” and “CSS” and see how many files you’ve got. Some are included inline (<style type="text/CSS"> and non-src <script>) and some are external (<link rel="stylesheet">, @import, and <script src>).
Inline includes bloat page size of the html. External includes ratchet up the number HTTP requests that a browser must make. The external includes are a bigger culprit in slowing down your site; it’s better to have make 1 HTTP request of a 2k external JavaScript than 2 HTTP requests of 1k files. In fact, it’s probably still better to make 1 HTTP request of a 4k file than 2 requests of a 1k file; the total download time will be similar, and on subsequent page views, the browser needs to check on the Last-Modified status of 1 file rather than 2. A highly technical analysis of this concept is at “Bulk File Transfer Measurements,” where you’ll see that throughput is poor until file size is at least 10k.
Step 2: Consolidate
Create consolidated JavaScript and CSS files. Copy the plugin-generated JavaScript and CSS into these files.
Note: It’s a good idea to make these consolidated files separate from your theme’s CSS/JavaScript, as you’ll want the consolidated plugin files to be portable when you change themes.
Step 3: Disabling the inclusion of the CSS/JavaScript from the plugins
This is the trickiest part, which is why I recommend this exercise only if you’re an advanced user. You should be careful here, as it’s really easy to mess things up. The best thing to do is to deal with one plugin at a time, iteratively reloading your cache-disabled blog to make sure things are still cool.
First you’ve got to find the plugins that are inserting the CSS and JavaScript. You might not know which plugins are responsible. For this task, do some grep’ing in the plugins directory (/path/to/wp/wp-content/plugins).
Good starting points: grep -Hnr "add_filter('wp_head'" *.php and grep -Hnr "add_action('wp_head'" *.php
This looks for plugins that are inserting something in the <head> of the document.
You can also grep for unique names in inline styles or JavaScript. External files should be clearer, as the includes should reference the plugin name somehow, since the files are often in the plugin’s subdirectory.
Once you find the responsible plugins, comment out the add_filter (i.e. // add_filter), or do whatever you’ve got to do in the plugin to disable inclusion.
Step 4 (optional): GZip it!
The consolidated files should be static; that is, they’re never going to change unless you install a new plugin that adds its own CSS and/or JavaScript. Because they’re static, you can gzip the consolidated CSS/JavaScript files for faster download. All browsers can handle gzipped files, and the filesize after compression is about 1/10 of its uncompressed size.
Simply execute: gzip stylesheet.js and it’ll created stylesheet.js.gz. You can then include this gzipped file, and the browser will understand (from the Content-Type returned by the web server) that it needs to unzip the file.
Step 5 (optional): Apache trick
One last thing.
Seems few people like to do this, but I think it’s handy. Instead of having:
<link rel="stylesheet" href="/path/to/stylesheet.js.gz" />
in your templates, I prefer this:
<link rel="stylesheet" href="/path/to/style/" />
This way, you can:
- Silently change the stylesheet returned by the HTTP request for that directory. You simply change the Apache configuration rather than having to update multiple HTML files or includes to reference the new file. As long as all of your templates — even non-WP templates — reference the directory, you’ll never have to worry about referencing an non-existent external JavaScript or CSS file.
- Serve a gzipped file transparently and not confuse people as to why the file extension is “.gz”.
For the above example, create a .htaccess file in the directory of your stylesheet and use the DirectoryIndex directive:
DirectoryIndex stylesheet.js.gz stylesheet.js
This means that when a browser requests that directory, it will be fed stylesheet.js.gz (if it exists) before stylesheet.js (if it exists). This order ensures that (a) the gzipped, smaller file is fed first, and (b) if you gunzip the file to modify it and forget to re-gzip it, you won’t have a problem.
Conclusion
WordPress users with lot of plugins might have 5 or 6 extra JavaScript and CSS files included, often externally. This increases the number of HTTP requests and slows down page load. Consolidating and gzipping the plugins’ JavaScript and CSS improves user experience.
October 1st, 2006 at 4:12 am
[...] Einen sehr interessanten Ansatz zur Performancesteigerung eines Wordpress-Weblogs liefert Tom Sherman in seinem Artikel “Consolidate CSS and JavaScript in WordPress“. [...]
October 5th, 2006 at 11:00 am
Featured on BuzzTracker…
…
February 1st, 2007 at 7:28 am
I have a question:
I’m starting with the set up of kubrick to make my own theme, but how can I change the styles.css file from its place? I want to create a folder called /code/ where I want to put styles.css which will contain @imports to my separate css files…
Where do I change the stylesheet_directory?
Thanks
February 1st, 2007 at 1:04 pm
In the WordPress theme header (header.php).
September 21st, 2007 at 3:14 pm
[...] dailyApps suggests to dynamically gzip the stylesheet and JavaScript to reduce the HTTP download. jotsheet goes even further, a neat method is demonstrated to consolidate all the CSS/JavaScript into one to save the HTTP request. [...]
September 21st, 2007 at 3:15 pm
[...] dailyApps suggests to dynamically gzip the stylesheet and JavaScript to reduce the HTTP download. jotsheet goes even further, a neat method is demonstrated to consolidate all the CSS/JavaScript into one to save the HTTP request. [...]
November 6th, 2007 at 1:48 am
[...] more responsive. Unfortunately, this is an even more annoying problem to solve. See these posts [1, 2] for some ideas. Social [...]
November 11th, 2007 at 9:18 pm
[...] JS files that you cannot eliminate, you can combine them into one big CSS file and one big JS file. This post has some advice for people who want to attempt manually consolidating CSS and JS. Be warned that [...]