Something that goes without saying is that the load time of a page is important. Google takes load time into consideration with it’s indexing algorithems. It’s not as big of a consideration as say, relevance, but it matters. In the grand scheme of things, what do a few seconds matter? Turns out they could matter quite a lot.
According to surveys done by Akamai and Gomez.com, nearly half of web users expect a site to load in 2 seconds or less, and they tend to abandon a site that isn’t loaded within 3 seconds.
If that’s the case, then sites with a lot of content running off of a CMS would probably be advised to minimize the size and number of requests being made to load their pages. That’s where this article comes in. I’ve recently redesigned my own site while still using WordPress and at the end of the process spent some time doing just that, minimizing requests.
Here’s a wonderful infographic from First Site Guide with a few suggestions on the topic and more reading below:
Database Requests in Themes
If you’re developing a theme for mass distribution then it’s going to be difficult for you to cover all the possibilities that might be required of a theme and cut down on database requests. If, however, you have purchased a theme or are developing your own you can do your best to reduce the number of times your theme needs to make a request of the database. One of my favorite ways to do this is by reducing the number of times you call
If you think about the number of times a theme might need to use this function it can get rather extensive. There are parts of the
<head> that will only call it once, like charset, and there are parts that you’ll need over and over again like ‘stylesheet_directory’. These parts in particular can be lessened by storing those parts in a variable or in an array and reusing that instead of making the call every time you need it.
Below is a sample of some code at the top of my
// =============================== // Reducing database calls // http://jeremyhixon.com/sandbox/snippet/reducing-database-calls-using-bloginfo/ // // Global variable used to reduce database queries on values commonly requested in themes. // Use 'global $bloginfo;' at the beginnng of any theme file and/or function to be able to access the values. // =============================== global $bloginfo; $bloginfo = array( 'name' => get_bloginfo('name'), 'description' => get_bloginfo('description'), 'admin_email' => get_bloginfo('admin_email'), 'wpurl' => get_bloginfo('wpurl'), 'stylesheet_directory' => get_bloginfo('stylesheet_directory'), 'stylesheet_url' => get_bloginfo('stylesheet_url'), 'rss2_url' => get_bloginfo('rss2_url'), 'charset' => get_bloginfo('charset'), 'language' => get_bloginfo('language'), 'text_direction' => get_bloginfo('text_direction') );
This code creates a
$bloginfo array that I can load at the top of every one of my theme files by stating
global $bloginfo; and then use it as many times as I need without creating any additional database queries. This can certainly be trimmed to suit your needs. As I said before things like ‘charset’, ‘language’ and ‘text_direction’ will only be used once if at all.
Compression, Expires and Caching
A few more server side tweaks here, this time using Apache. In this instance we’re using a little gzip compression and some Apache settings to control when the browser updates it’s copy of the files we’re using in our theme. These tweaks are super easy, as long as your server is configured correctly, as they all take place in the
Gzip Compression with mod_deflate
# Use Mod_deflate to compress static files <ifmodule mod_deflate.c> <filesmatch '.(js|css|ico|txt|htm|html|php)$'> SetOutputFilter DEFLATE </filesmatch> </ifmodule>
<IfModule mod_expires.c> ExpiresActive On ExpiresDefault 'access plus 1 year' </IfModule>
Above, we’re sending a note to the browser informing it that after it’s downloaded files from our server that it won’t need to download them again for another year. What’s up there is a very harsh setup as it’s not specific to any one kind of file. But that’s what I use on my CDN to speed things up. You may also set specific rules for specific mime types such as:
<IfModule mod_headers.c> <FilesMatch '\.(bmp|css|flv|gif|ico|jpg|jpeg|js|pdf|png|svg|swf|tif|tiff)$'> Header set Last-Modified 'Mon, 31 Aug 2009 00:00:00 GMT' </FilesMatch> </IfModule>
Here we’re setting the “last-modified” header for any of the files that fit into the
FilesMatch parameter to a date very far in the past. This gives the browser the impression that the file hasn’t changed in some time and, thus, doesn’t need to download it again once it has it stored locally. The targeted files in this case are media files that, typically, don’t change, like images and videos.
One of the more mundane aspects but also one of the more essential and certainly one of the most often overlooked tweaks is image optimization. Photoshop has it’s “Save for Web” dialog. When you upload an image through WordPress’ media manager it gives you a status during the process of “crunching”. But I’m not just dead sure that this is enough. When it comes to really squeezing the last little bit of file size out of an image I only use one tool, ImageOptim.
Even a file that’s been “saved for web” and “crunched” will be further reduced in size by ImageOptim. It finds the optimal compression format for your image and also removes comments and color profiles. It works with PNGs, JPEGs and even GIFs.
Another great way to minimize the request size, polyfills are something I initially began considering because of a “mobile first” website I was developing. The one I have been using is called Picturefill by Scott Jehl. What Picturefill essentially does is take advantage of media queries to look at the size of the viewport loading your site and then load an image appropriate to that size. There is no image loaded initially so if the user visits on a mobile device with a very small screen Picturefill will load a much smaller image. This takes less time to load, and thus, speeds up your site.
Combining CSS and JS Files
Log out of your WordPress site so that you see what your readers get when they visit your site. View the source of your page and take a look at the
<head> of the page. Make a note of all the
<link rel="stylesheet"> references you see. Create a file called
style.combined.css in your theme folder, wherever you like to put your CSS files. This will serve as the point where we consolidate all of our CSS files into one.
Go through each of the stylesheets you found and copy/paste them into the file you created. Try and keep them in the order they are in the source if you can as well. That will keep you from having any unfortunate and unexpected styling changes when you’re done.
After combining all the CSS into one file it’s time to go through and remove all the stylesheets you were pulling from. This could be time consuming. Some plugins like Contact Form 7 have globals that you can set to turn off the inclusion of it’s included stylesheets and scripts. Most will probably not have such an option so you’ll have to remove them yourself. If you follow the instructions on this article it should prove fruitful. If after following the steps in that article you still have styles that won’t go away, you may have to dig around in the plugin files themselves to remove them. If you can avoid this I would because as soon as you update that plugin next the style will, most likely, come back.
Once you’ve cleaned up the styles add in your
style.combined.css file in whatever fashion you choose and thoroughly test the site.
<script> elements in your page’s source and make note of them (in order). Once you have your list create a
scripts.combined.js file and begin to copy/paste the code from the files on your list in.
Once you have all your scripts wrangled into one file start doing the same with the scripts from your list that you did with the styles in the previous step. The same process’ should apply because the above article also covers the removal of scripts being placed by plugins.
This script will allow you to load your script(s) as the page renders instead of requiring they be loaded before the page can continue to load. The
getScript function has a callback that enables you to load scripts in a certain order if the need arises. For instance, your scripts might be dependent upon jQuery being loaded to run. In this case you would use the first
getScript to load jQuery and then, within that functions callback you’d use another
getScript to call your scripts file.
If you’ve gone through all the trouble above you should be thankful that this is what I’m ending on. Minifying is so simple and easy because there are a number of tools out there to do it for you. If you’ve compiled all your styles and scripts into a single file then you probably have 2 VERY large files now. Files that can be compressed to speed up their load time as well.
If you choose to do it yourself, I like YUI Compressor because it can compress your JS and CSS files on the same page, though not at the same time ;-). I’ve used this numerous times and have never gotten a bad result from it. You just copy/paste your code into the window, choose what it is your compressing, make whatever changes you want in the checkboxes (though I never do) and hit “Compress”. You’ll be taken to a window below with the compressed version of your code to be copy/pasted back into your original file. Cake.
No matter what method you use to minify your files I cannot stress enough that you test, test, test your site to make sure all the functionality is present after the modifications.
I hope you’ve enjoyed reading as much as I did toiling over the details to actually accomplish this on my website for the first time. It’s no small task but the rewards could be fantastic. If nothing else you’ll have a site that loads as quickly as possible and that should make your viewers happy. Which should make you happy. Cause that’s why were here. Sharing information.
If you have any insights or recommendations please share. I’m here to learn as well.