Speeding up Jishnu even further….

Ok, so Jishnu is already quick. 1 tiny image, and no javascript (aside from jQuery that WordPress includes by default). If you looked at the comparison page, you probably noticed that by default on a fresh blog, with proper .htaccess settings (you know, so the server compresses things and sets nice headers and all that) it scores 95% on PageSpeed and 94% on YSlow!.

So how do we get this:

Jishnu Speed Test Screenshot

To do this?

Jishnu PageSpeed and YSlow


First: Where there’s a will, there’s a way (yes, I pulled out all the tricks to get that score).

Second: While PageSpeed and YSlow are good indicators, they’re not a hard-and-fast rule. In fact, some of the things I did to reach that score actually made the site slightly slower (in terms of the total page-load time for real visitors) and I ended up turning a few things off.

If you’re really aiming for that 100% mark, it’s often as simple as ditching external javascript (no adsense/analytics), using W3TC to combine your CSS & javascript and load the JS as non-blocking in the footer, setting up proper caching in .htaccess (W3TC can actually do this too, mind you), disabling query strings (which you can do in the Jishnu Advanced Options, though I kinda recommend against it since it can cause problems with stale CSS/JS), and… well that usually about does it.


Like I said though, a high PageSpeed/YSlow score isn’t everything. Your goal should be to focus on the page load time for users.


So that said, you’re already using one of the quickest WordPress themes out there, so let’s look at a few more things you should consider doing…


Try to get scripts out of the head and into the footer

This one is one of the hardest things to pull off. Don’t get me wrong, moving the scripts is easy. Sadly, a lot of plugins and features require some sort of javascript to be called in the head. Before I discourage you before you’ve even tried, let’s look at the potential benefits:

Jishnu before any tweaks


Above, you see a “waterfall” for a typical post with 7 images on a WordPress site running Jishnu after a fresh install. A brief explanation as to what you’re seeing, just in case you aren’t familiar with these:

  • The time moves left to right. The left side is T=0 (the moment we tried getting the webpage). The right-side is when everything has finished loading (roughly a second later). Each bar represents a file that Firefox is getting to load the page.
  • The first bar (top one) is the HTML itself. If you’ve ever done “View Source” on a webpage, that’s essentially what this is.
  • The next 3 bars (that start at the same time) are the CSS stylesheet, and 2 JavaScript files. You’ll notice they start at the same time.
  • The remainder are images that were in the post, except the last 1 which is the image sprite the theme uses.

You might notice that all those images take a while to start. In fact, they wait until after the CSS and javascript have finished. This is because that javascript is in the <head> section of the page, which “blocks” everything that comes after it. The details as to how and why this happens are a little beyond the scope of what I’m trying to convey here, so let’s just see what happens when javascript is moved to the footer:

Jishnu after moving javascript

Notice the difference?

All we did was move that javascript to the bottom and suddenly, just about everything tries to load (or “parallel download”) at the same time! This is pretty nifty.

You might wonder why that last file is a bit of a straggler. Actually, it’s the image sprite that the theme uses, and by default it isn’t called until the CSS is loaded. If you look at where the CSS download ends (that’s the 2nd file), you’ll see it lines up with where the last file starts.

Let’s pretend we’re all hard-core and OCD about things lining up….




Ok, so how did we do this? Actually, in Jishnu Options, there’s an “Advanced Options” section (you know, the one with the big red warning).

All we did was check the following 2 boxes in the Tweaks to HEAD, Performance Tweaks, SEO, and Miscellaneous area:

  • Preload image sprite (for that last one!)
  • Move jQuery to footer (update: I recommend using a plugin for this now)

To move jQuery to the footer, I recommend using a plugin called Autoptimize rather than the setting built into Jishnu. Autoptimize will actually gather all your scripts (though you can exclude some if necessary) and load them in the footer in a “deferred” way which shouldn’t block the page load. It can also combine your CSS, and minify both of those (plus the HTML). I suggest setting the plugin to INLINE your CSS because the page will tend to “show up” much quicker for visitors the first time they visit your page. Separate CSS files always result in an extra request and usually all that overhead adds additional time. Autoptimize also works out-of-the-box with Jishnu.

If you’re using other performance-oriented plugins, I suggest enabling the Autoptimize settings one-at-a-time so that if something gets wonky you can narrow it down. As an example of something “wonky”, if you have W3TC installed and have the “minify” section enabled for the HTML, trying to optimize the HTML in Autoptimize too will give you the following message:

PHP message: PHP Fatal error: Cannot redeclare class Minify_HTML

So enable things gradually, checking to make sure everything works after each change. Remember, the plugin works great with Jishnu but that doesn’t mean all your other plugins will get along with it!

All that being said, moving jQuery to the footer can be risky business. Some plugins really rely on it to be in the head. If you go this route, you might want to start by disabling all your plugins, enable the JS-related settings, make sure everything works, and then start enabling plugins again one at a time. Don’t let the potential pitfalls discourage you though – the performance gains by getting javascript out of the head and loading it in a deferred way are pretty significant.

(now is probably a good time to mention that if you’re using Google Analytics, rather than using a plugin to insert the code, you can manually put the code in your HTML very easily with Jishnu by plugging it into the Custom HTML section).

Moving on to plugins…


“Use Google Libraries”

Wed Aug 7th 2013 Note: I hit an issue in WordPress 3.6 where replying to comments from within the backend no longer works with this plugin enabled. I’m assuming the plugin will be updated at some point to address the issue, but I’ve been seeing better improvements by simply using the Autoptimize plugin mentioned previously.

Use Google Libraries (author link here) is a plugin. Normally, your site serves up the jQuery that comes with WordPress to all your visitors. It’s only 33KB (compressed), but let’s face it – that’s bigger than everything else in the theme put together. It also has a “query” string added to it, which means it won’t be cached by some proxy servers.

The solution? Google has jQuery available for anyone to use. And the “Use Google Libraries” plugin will tell WordPress to use that one instead. 4 quick benefits…. First, there’s no query string. Second, Google’s servers are… probably a little bit faster and a bit more distributed-around-the-world than the one your website is running on, so it should load lightning-fast for somebody on the other side of the world. Third, because a large number of sites are doing this, there’s a good chance the Google version will ALREADY be cached by your visitor before they even arrive on your site!. So they won’t have to download it at all when your page loads! And fourth, it’s a little less data transfer (and one less file request) coming from your end.

That on it’s own is great, and even if you do *nothing else* (no W3TC, etc), it’s a smart thing to use.

The only downside… in order to be “safe”, it checks every so often to make sure that jQuery is still up on Google, so there’s the potential for a page load to take a little extra time every so often when it wants to check. Oh, and it creates an insane number of PHP ticks (over 300) which might give you a miniature heart attack if you watch that sort of thing.


WP-Smush.it and others

I’ll admit it, I’m bad when it comes to uploading images on a page. Those images at the top…? They’d probably be half the size if I’d converted them to JPG’s before uploading.

One thing you *can* do though is install WP-Smush.it (author link here). It will automatically “Smush” the images you upload to your site. For those who aren’t in-the-know, when you take a screenshot, save an image from your camera, or save a picture in paint or photoshop, it isn’t always saved as efficiently as possible. WP Smush it will run your images through a few algorithms to make them smaller.

An even better (but manual) option for Mac users is to use ImageOptim. It uses a number of tools to squeeze down the size of images – typically getting them smaller than any other program out there does. Unfortunately I’m not aware of any Windows-based all-in-one solutions that even come close to comparing (though saving in Adobe Fireworks can get it close enough for Smush-it to get close).

Typically, what you’d do with ImageOptim is zip your entire wp-uploads folder, download it, unzip, and drag it right into ImageOptim. Let it go to work on all your images and once complete, re-zip, upload it, and copy it over the originals (be careful to hang on to the original zip file and any backups just in case something goes wrong). From then on, every so often you could just zip up the last few months worth of images and repeat the process. Or better yet, use ImageOptim before you upload your images (though it won’t help the thumbnails that way).

Just to emphasize how beneficial these things can be, the images I have on the previous page… ImageOptim shrunk them by 40%.


Use a cache program (Lite Cache, Hyper Cache, W3TC, Super Cache, etc)

If you remember in the images from previous pages, we were looking at roughly 800-1000 ms (just under a second) for the page to load.

Actually, each of those purple bars were the browser waiting on the server (which includes WordPress) to piece together each page – the downloading part was so quick, you probably can’t see it in the images (look for a dark green sliver at the end of each bar).

Let’s see what Lite Cache does:

Lite Cache in action on Jishnu

The bars look similar (it always stretches them to fill the screen), but look closer… Look at those times!

We went from 804 ms all the way down to 528 ms!

That’s because the page itself went from over 400 ms down to about 130 ms!

Here’s a comparison to help show it:

Lite Cache vs Regular

Yes, Lite Cache is impressive. And so are the others I’m about to mention!


Here’s a quick list of common cache plugins for WordPress:

  • Lite Cache (author link) which we looked at above is very simple, clean, and efficient, but can be slightly complicated to set up unless you’re familiar with adding values to wp-config.php and .htaccess (it tells you what to add, mind you and it only takes 20 seconds or so).
  • W3TC (author link) is easier to set up (it injects the changes into wp-config and .htaccess for you), is the most popular, is most flexible, and can also combine/minify your CSS & Javascript (amongst other performance enhancing tricks). It’s a little more heavy-weight, but is more of a 1-stop-shop when it comes to performance. Note that you want to be careful not to simply enable everything in W3TC. If you’re a beginner, start with Disk:Enhanced caching, and perhaps minifying CSS & JS (and moving the JS to the bottom if you can). You can move on to Browser Caching stuff later. I recommend against using the Database or Object cache unless you understand what they do. W3TC is very powerful, but with power comes the ability to shoot-yourself-in-the-foot if you blindly start messing with things you don’t understand.
  • WP Super Cache (author link) is another popular one with it’s own set of features, and should also be easy to set up (I believe it also injects changes for you).
  • Hyper Cache (author link) is created by the person who makes Lite Cache. Hyper Cache has been around longer, and could also be worth a look.

Note that the cache programs I’ve tended to use in the past have been Hyper Cache and W3TC. This was the first time I’d actually used Lite Cache (figured I’d check it out while testing). I always liked the simplicity of Hyper Cache, and W3TC tends to do the best job when it comes to combining/moving JS, particularly when you’re aiming for a JS file without a query string.


As a side-benefit, the caching programs can all reduce server load, since WordPress doesn’t have to regenerate the page for each and every visitor.

Oh, and if you’ve never used a caching plugin before…. only install ONE.


.htaccess stuff – caching and compressing

The vast majority of people have their sites hosted on a Linux host, running Apache. And most of the time, there is an .htaccess file in your web directory. Here, you can set up a few extra rules for Apache when serving up your content.

This isn’t specific to WordPress, but can keep things quick for frequent visitors. Somebody shared it quite some time ago, and I’ve used it on a few sites. Note that W3TC (mentioned last page) adds similar things if you make use of the “Browser Cache” setting there, so if you’re using it, no need to go plugging this stuff in.

Most of this “checks” to make sure your server allows you to use each rule, but just-in-case something goes wonky, make sure you quickly check your site after saving this to .htaccess to ensure your site still works! If it doesn’t, you’ll want to quickly remove it and save again.

It’s a little small, because…. well, it’s kinda long. Details afterwards (which you should read!).

# BEGIN Browser Caching/Headers
<IfModule mod_mime.c>
AddType text/css .css
AddType application/x-javascript .js
AddType text/richtext .rtf .rtx
AddType image/svg+xml .svg .svgz
AddType text/plain .txt
AddType text/xsd .xsd
AddType text/xsl .xsl
AddType video/asf .asf .asx .wax .wmv .wmx
AddType video/avi .avi
AddType image/bmp .bmp
AddType application/java .class
AddType video/divx .divx
AddType application/msword .doc .docx
AddType application/x-msdownload .exe
AddType image/gif .gif
AddType application/x-gzip .gz .gzip
AddType image/x-icon .ico
AddType image/jpeg .jpg .jpeg .jpe
AddType application/vnd.ms-access .mdb
AddType audio/midi .mid .midi
AddType video/quicktime .mov .qt
AddType audio/mpeg .mp3 .m4a
AddType video/mp4 .mp4 .m4v
AddType video/mpeg .mpeg .mpg .mpe
AddType application/vnd.ms-project .mpp
AddType application/vnd.oasis.opendocument.database .odb
AddType application/vnd.oasis.opendocument.chart .odc
AddType application/vnd.oasis.opendocument.formula .odf
AddType application/vnd.oasis.opendocument.graphics .odg
AddType application/vnd.oasis.opendocument.presentation .odp
AddType application/vnd.oasis.opendocument.spreadsheet .ods
AddType application/vnd.oasis.opendocument.text .odt
AddType audio/ogg .ogg
AddType application/pdf .pdf
AddType image/png .png
AddType application/vnd.ms-powerpoint .pot .pps .ppt .pptx
AddType audio/x-realaudio .ra .ram
AddType application/x-shockwave-flash .swf
AddType application/x-tar .tar
AddType image/tiff .tif .tiff
AddType audio/wav .wav
AddType audio/wma .wma
AddType application/vnd.ms-write .wri
AddType application/vnd.ms-excel .xla .xls .xlsx .xlt .xlw
AddType application/zip .zip
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css A31536000
ExpiresByType application/x-javascript A31536000
ExpiresByType text/richtext A3600
ExpiresByType image/svg+xml A3600
ExpiresByType text/plain A3600
ExpiresByType text/xsd A3600
ExpiresByType text/xsl A3600
ExpiresByType video/asf A31536000
ExpiresByType video/avi A31536000
ExpiresByType image/bmp A31536000
ExpiresByType application/java A31536000
ExpiresByType video/divx A31536000
ExpiresByType application/msword A31536000
ExpiresByType application/x-msdownload A31536000
ExpiresByType image/gif A31536000
ExpiresByType application/x-gzip A31536000
ExpiresByType image/x-icon A31536000
ExpiresByType image/jpeg A31536000
ExpiresByType application/vnd.ms-access A31536000
ExpiresByType audio/midi A31536000
ExpiresByType video/quicktime A31536000
ExpiresByType audio/mpeg A31536000
ExpiresByType video/mp4 A31536000
ExpiresByType video/mpeg A31536000
ExpiresByType application/vnd.ms-project A31536000
ExpiresByType application/vnd.oasis.opendocument.database A31536000
ExpiresByType application/vnd.oasis.opendocument.chart A31536000
ExpiresByType application/vnd.oasis.opendocument.formula A31536000
ExpiresByType application/vnd.oasis.opendocument.graphics A31536000
ExpiresByType application/vnd.oasis.opendocument.presentation A31536000
ExpiresByType application/vnd.oasis.opendocument.spreadsheet A31536000
ExpiresByType application/vnd.oasis.opendocument.text A31536000
ExpiresByType audio/ogg A31536000
ExpiresByType application/pdf A31536000
ExpiresByType image/png A31536000
ExpiresByType application/vnd.ms-powerpoint A31536000
ExpiresByType audio/x-realaudio A31536000
ExpiresByType application/x-shockwave-flash A31536000
ExpiresByType application/x-tar A31536000
ExpiresByType image/tiff A31536000
ExpiresByType audio/wav A31536000
ExpiresByType audio/wma A31536000
ExpiresByType application/vnd.ms-write A31536000
ExpiresByType application/vnd.ms-excel A31536000
ExpiresByType application/zip A31536000
<IfModule mod_deflate.c>
<IfModule mod_setenvif.c>
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
<IfModule mod_headers.c>
Header append Vary User-Agent env=!dont-vary
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE text/css application/x-javascript text/html text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon
<FilesMatch "\.(css|js|CSS|JS)$">
<IfModule mod_headers.c>
Header set Pragma "public"
Header append Cache-Control "public, must-revalidate, proxy-revalidate"
FileETag MTime Size
<FilesMatch "\.(rtf|rtx|svg|svgz|txt|xsd|xsl|RTF|RTX|SVG|SVGZ|TXT|XSD|XSL|)$">
<IfModule mod_headers.c>
Header set Pragma "public"
Header append Cache-Control "public, must-revalidate, proxy-revalidate"
FileETag MTime Size
<FilesMatch "\.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|swf|tar|tif|tiff|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip|ASF|ASX|WAX|WMV|WMX|AVI|BMP|CLASS|DIVX|DOC|DOCX|EXE|GIF|GZ|GZIP|ICO|JPG|JPEG|JPE|MDB|MID|MIDI|MOV|QT|MP3|M4A|MP4|M4V|MPEG|MPG|MPE|MPP|ODB|ODC|ODF|ODG|ODP|ODS|ODT|OGG|PDF|PNG|POT|PPS|PPT|PPTX|RA|RAM|SWF|TAR|TIF|TIFF|WAV|WMA|WRI|XLA|XLS|XLSX|XLT|XLW|ZIP)$">
<IfModule mod_headers.c>
Header set Pragma "public"
Header append Cache-Control "public, must-revalidate, proxy-revalidate"
FileETag MTime Size
# End Browser Caching/Headers

Again, make sure you’re using an editor that won’t break down if for some reason pasting this into .htaccess breaks your site. If you’re on a host that uses cPanel, the editor that comes with the file manager will do fine.

For a quick (but important!) explanation, this is essentially what this stuff does:

  • Adds a lot of “types” based on file extensions.
  • Adds expiration dates to different types of files. Note that many of these types are set to 1-year (31536000 seconds, actually). So after a browser grabs one of your javascript files, if it still has it in it’s cache 360 days from now, it will use that same file. This is a double-edged sword. On one hand, it’s great that somebody can grab a javascript file, an image, etc., once and not have to get it again each time they visit your site. However, what if you change one of those files? Well, if it has the same name, your user is seeing the old version for up to a year. WordPress works around this for *it’s* stuff by appending “query strings” to the end of the javascript and CSS it serves up. Stuff like wp-admin.css?ver=3.5 (which is different than say, wp-admin.css?ver=3.4). In any case, it’s something to keep in mind. If a year seems a bit long for your files to be cached, you can always lower it. Note that the above does not set expiry dates on your actual content (the HTML), because that is very likely to change at any given moment.
  • Adds compression to “text” types of files (with exceptions for a few browsers that will hiccup if it’s set). Compression just on stuff like your HTML, CSS, javascript, etc. Things that compress easily.
  • Configures “ETags”. If that sounds boring, just skip to the next point. If you want to know what they are, keep reading…. Essentially, when the expiry date is reached, or if a visitor hits refresh on your site, their browser might still have a file in the cache but isn’t sure if it’s the latest one, so it sends a request with the “ETag” it has for files it would normally download – essentially a small checksum based on the file size and last-modified date. Your server can tell if the browser has the latest version based on that code, and if it does, it sends “304 – not modified” rather than sending the file. On the other hand, if the browser doesn’t have the latest version, it sends the new file. As for configuring it, what the code above does is set it to calculate the ETag based on file size + last modified date/time.
  • Adds some Cache-Control headers.

These are handy things that can help speed up your site, while increasing PageSpeed and YSlow scores. Do use them with caution though – if you constantly change files that would normally be static for a long period of time, at the very least you may want to dig in and modify the expiry time.

<< click here to head back to the main Jishnu page >>