Optimizing a WordPress Blog for Speed

optimized-post-imageYour new theme is finished and live. You’ve squashed some remaining bugs. Maybe even added your favicon that was forgotten. Your blog is ready for the flood of traffic that is about to pour in, except for one thing.

It’s time to optimize your WordPress theme so that visitors get a snappy load time when they visit, and so that your host doesn’t come to it’s knees if you get a flood of traffic from something like Digg or SlashDot.

This post will show how I optimized this blog and reducing its size by over 1MB and shaving over 3 seconds from its load time, with a step-by-step guide with screenshots of what I did.

Before Optimization

Here’s a collection of screenshots from various speed testing tools I used to capture my unoptimized blog.

Firebug Net Console

Firebug is the world’s greatest plugin for Firefox. I’m not going to go into it’s greatness, but just encourage you to go get it.

I captured the results from 5 tests on my site to get a decent average load time. Each time I reloaded I used ctrl-F5 which forces the cache to be reset and pulls the files from the server again.

The average time from the tests was 7.31 seconds.

Here’s some firebug screenshots for the test run that was closest to the average.

firebug_all_beforefirebug_html_beforefirebug_css_beforefirebug_js_before

YSlow

YSlow is a firebug plugin from Yahoo that grades your site and gives suggestions on things to do to make it faster

yslow_grade_before yslow_components_beforeyslow_stats_before

Page Speed

Page speed is a new firebug plugin from Google that I wanted to try out. It gives pretty much the same data as YSlow does.

pagespeed_before

Website Optimizer

I wanted to use this site because hopefully their hardware produces more standard results. I can run a test on my browser 10 times and get up to a 3 second variance on some tests, just due to network issues that might occur.

wso_before

wso_before2

Optimization Phase 1: CSS and Javascript

Keep in mind as you go through this post that speeds and even files that get loaded vary. I don’t have anything close to a perfect environment for doing optimization testing, so don’t become too fixated on some of the randomness.

The first thing that I’d like to do is optimize my CSS and javascript files.

CSS Compression

For CSS I originally installed the Script Compressor WordPress plugin. This plugin does what it called real-time compression. Real-time compression is nice, because it compresses all of the CSS that is served by your site and it allows you to easily make changes to your current CSS and FTP it without having to manually compress your CSS. This type of compression is good for WordPress also because there will be other CSS files that your site uses that you did not create.

For example, I use the CForms  II plugin for my contact page. That plugin includes its own CSS to layout the contact form, I chose the minimal.css for mine. If I were to manually take that CSS and compress it, then when the author updates his plugin, I would have to remember to go back and recompress it. With real-time compression, it gets compressed automatically whenever someone visits the site.

The plugin worked fine, but the screenshots below reveal a problem.

firebug_css_before

firebug_css_after_realtimecompression

Although all my CSS files were reduced in size, it actually took longer for my pages to be rendered. The reason for this is because of my host. I have one of the cheaper economy hosts, so I get what I pay for in terms of hosting power. So since the real-time compression happens when someone loads the page, it’s faster to just serve the uncompressed CSS than it is to take the CPU cycles to compress the CSS and serve the smaller file.

The moral of this is: Don’t assume that just because you have compressed CSS files that your site is loading faster. Test it.

So since the real-time compression won’t work in my situation, I decided to do an manual compression. I tested a couple manual compressors and found csscompressor.com to be the best. Some of the others I tried failed to understand some basic CSS selectors and chose to remove every scrap of whitespace, which destroyed my site.

For example, #middle #character { some: styles } gets compressed to #middle#character{some:styles} which makes that style worthless because I need the space between #middle and #character.

I compressed my main stylesheet, monsta.css and I used the highest compression method.

It yielded a good reduction in size from 22k down to 16k and a small decrease in load time.

firebug_css_after_csscompression

I decided to compress the other files that are over 1k in size, minimal.css, lifestream.css and calendar.css.

Minimal went from 9k to 5k.

Lifestream went from 2k to 1k.

Calendar went from 2k to 1k. Calendar doesn’t seem to get loaded on refreshes anymore.

firebug_after_csscompress2

Total size saved after CSS compression was 12k, not too shabby.

Javascript

This step might not be needed for your blog, but I use a good bit of jQuery to get my sidebar to do some some of it’s fancy stuff.

Here’s the javascript load screen before optimization and while looking over it I noticed one very inefficient thing happening.

firebug_js_before

If you noticed in the screenshot, I am loading jQuery twice.

WordPress has been including the jQuery library with all installs since version 2.2 to handle their backend, so that explains why the second call appears. So one might think that all that has to happen is to remove one’s jQuery call from one’s header.php file and all would be peachy. Well, it turns out, one, would be wrong and would break their site if they did so and forget to check it for a day. So after some more research here’s the correct way to solve the problem without running into issues.

This, Loading jQuery Correctly in WordPress post, provided most of the help with another tweak at the end.

I removed my call to jQuery from my header.php file

I added

<?php wp_enqueue_script("jquery"); ?>

directly above my <?php wp_head(); ?>

Then I put my custom jQuery file, montsa.js, below wp_head()

Finally, one last tweak since WordPress puts it’s jQuery in what’s called “no conflict” mode. No conflict is done so that the default jQuery shortcut , $, doesn’t conflict with other javascript libraries such as Prototype. To fix that change your standard jQuery document ready line from this

$(document).ready(function() {

to this

jQuery(document).ready(function($) {

That should be about it for getting jQuery to play nice with WordPress.

JS Compression

There are a few tools to do this also, but since I liked csscompressor so much I figured it best to use it’s sister javascriptcompressor.

My monsta.js went from 4k down to 2k after the compression. I also shaved about 1.5k from some other jQuery used internally within a file.

Optimization Phase 2: Images

Using Sprites

Sprites are a technique to reduce the number of HTTP requests to the server by adding multiple images into one image and then using CSS background-image and background-position to show the desired image.

Here are a few good posts describing what they are and how to use them much better than I can. Advanced CSS Menu The Mystery of CSS Sprites CSS Sprites

Since I’ve been using sprites for a while I tend to already design and markup using them, so I couldn’t really find anywhere that I could easily add them. Perhaps you can use this optimization technique better for your blog.

Image Sizes

I produce most of my images as PNGs from Adobe Fireworks. When doing so, Fireworks adds extra information to each image so that the PNGs can be better edited when opened again in Fireworks. That’s fine, except that it can create some large file sizes. So now I needed to reduce each image down to its bear necessities. I opened each image in Photoshop CS4 and used the “Save for Web and Devices” option under File.

Although each image looks just the same as it did before, there were some remarkable size reductions.

The total size for images went from 2.27MB to 1.66MB, a .61MB total reduction.

firebug_images_after_imagesave

I could further reduce the image sizes if I were to go through some of my posts and optimize the first image of each post, since my theme uses the first image from each post as the thumbnail image if I don’t specify another image. So some of the images being loaded into the 210px thumbnail are actually 500px images just reduced in size.

Phase 2 Results

So after 2 phases of optimization we’ve gone from weighing in at 2.47MB to trim 1.8MB.

firebug_after_phase2

The load speed is skewed because I’m on an ethernet connection verses WiFi for the other screens.

Optimization Phase 3: Gzip Files

This is something that both YSlow and PageSpeed were both yelling at me to do.

Prior to WordPress 2.5 you had the option to gzip your files under the Reading options. But, for whatever reason, it is no longer present, so we must look to the Internet for some answers.

The best post that describes multiple ways to manually gzip your files is from The Bits 2.0.

There is also a gzip WordPress plugin you can install that explicitly does the gzipping, but if you just move on to the Phase 4 plugin I suggest, it does gzipping along with other things.

Note: After hours of research and trying various methods to get my site to manually be gzipped, I am chalking my lack of gzipping to my hosts inability to do so. If you know how to get Bluehost to gzip files, please let me know.

Optimization Phase 4: WP Super Cache

WP Super Cache is a plugin that most WordPress users install as soon as their site is up. It’s usually sufficient enough to be the only method of optimization, but I wanted to take my optimization further.

What it does is make copies of the generated WordPress pages in HTML so that when someone requests a page, they are given the smaller HTML file and aren’t using your host’s CPU cycles to generate the page every time someone visits.

Final Results

My optimization appears to have cut the total site size from 2.47MB down to 1.41MB, saving of 1.06MB.

The blog also went from an average load time of 7.31 seconds to around 4.5 seconds, a saving of nearly 3 seconds.

Here’s some screenshots from how the blog performs after it’s been optimized.

Firebug

firebug_all_end firebug_html_end firebug_css_end firebug_js_end

YSlow

yslow_endyslow_components_end yslow_statistics_end

Page Speed

pagespeed_end

Website Optimizer

wso_end1 wso_end2

What You Should Do, In a Nutshell

By reading this post you get the benefit of not repeating the mistakes I made, and trust me that alone can save you hours.

First, don’t manually compress CSS and Javascript first. It makes no sense to do it first, not sure why I thought I should. If you are going to make sprites or do anything to change your CSS or JS during optimization, then you have to uncompress the file, make whatever changes you need, then compress and FTP it again. Not a wise decision.

Second, get in a habit of saving images optimized for the web. Those bloated PNGs take up a ton of space and it takes time to go back through an optimize and update each picture. Make image optimization apart of your workflow.

Third, add jQuery correctly in WordPress. Under Phase 2, I discuss a dilemma of two jQuery calls being made and show how to fix it correctly. As AJAX is more prevalent, more plugins will be using jQuery as their javascript library. Making only one call will save wasted bandwidth.

Fourth, don’t worry too much about multiple HTTP calls . I researched a bit to try to find a better way to reduce the number of calls, by combining some files together or making huge sprites for the site to use, but came to this conclusion. Multiple HTTP calls are inherent with WordPress. Due to WordPress’ architecture of the plugin system, many small files get added to the blog loading sequence. I’ve decided not to worry too much about this and just let the problem remain.

If you can reduce HTTP calls by using sprites, then by all means us them, but trying to get 7 CSS files that come from various places into one file isn’t worth the hassle.

Other Optimization Resources

Here a few other posts I read that helped with my optimization efforts.

If you have any of your own optimization techniques, please share in the comments.

  • 1

    WP PHP Speedy is an older plugin (still works, even with 2.9-rare) that will take care of the JS and CSS minification and compression among other things. It’s a perfect companion to Super Cache.

  • 2

    WP Minify also does a great job combining/minifying javascript and css.

  • 3

    Fantastic post! It’s sad to see that it hasn’t gone viral yet. I’m trying to reduce the loading time of my website too and have succeeded to some extent. Your post helped a lot.