Customizing K2: Part 5

Hot on the heels of Part 4 comes Part 5. In Part 4 I spent a bit of time on using image maps to decrease load times and save bandwidth. I thought I would expand upon this and dedicate Part 5 to creating a faster loading blog. Most of these concepts can be applied to any website or blog, however they are meant for K2 as it is fairly loaded even at default. Hopefully, by the end of this article your blog and server will be able to handle mass-traffic, such as from Slashdot or Digg, much more easily and help you conserve costly bandwidth. Throughout this article, I used this website optimizer to find out how large each page is and how many items load.

NOTE: If you're going to copy and paste code, retype the quotation marks and apostrophes - when I posted this code, WordPress automatically changed them to the "fancy" ones and this breaks in code.

Script Slowdown

Weighing in at roughly 47kB, the prototype.js bundled with K2 r167 is a hefty JavaScript framework that allows your K2 blog to have things like livesearch, live commenting and rolling archives. (note that the newer, SVN versions of K2 use a lighter prototype at just 10kB) My general rule of thumb is that while this JavaScript adds some neat features it adds not only to the time it takes to download the file but also gives the browser the extra task of executing such a file. Unfortunately, I have been noticing a trend with many K2 mods using JavaScript effects to have items that control collapsable spaces. The less scripts your user's browser must download and execute, the better.

If you choose to sacrifice the amenities of livesearch and live commenting for the simplicity and rapid response of the traditional methods, make your way to WP Admin » Presentation » K2 Options. Disable both livesearch and AJAX commenting as below and save.

K2 Admin Options

If you don't like the ugly Go button that comes with the regular search box, you can disable it so that one must type in a query and hit enter to search. Open up searchform.php and find this block of code at the bottom:

<form method="get" id="searchform" action="<?php echo _SERVER['PHP_SELF']; ?>">     <input type="text" value="<?php echo wp_specialchars(search_text, 1); ?>" name="s" id="s" onfocus="if (this.value == 'find that elusive article') {this.value = '';}" onblur="if (this.value == '') {this.value = 'find that elusive article';}" />    <input type="submit" id="searchsubmit" value="go" />   </form>

You will want to comment out the second from last line in that snippet, as below. Luckily, even after removing the search button, pressing enter processes the search query.

<!--<input type="submit" id="searchsubmit" value="go" />-->

Plugins

If you are using the Rolling Archives plugin, deactivate that as well. As far as scripts go, if you are using Mint the more peppers you use, the larger the JS include will become. Most peppers, upon activation, add a bit of extra code to the javascript file. For example, my Mint JS include is roughly 9kB at the time of this writing, with over 10 peppers in use. I have seen other Mint JS files weigh in at only 3kB.

Load times can be increased not only dependent upon how many things need to be downloaded but also from which websites they come from. Loading 5 local files is nothing compared from 5 files each on different servers or websites. Serve as many of the files you can locally, unless your server is slow, then you can offload pictures to a service such as flickr.

Speaking of flickr, if you are using Dave's awesome flickrRSS plugin now is the time to either completely deactivate it or display a more reasonable number of photos, such as 4. If you cannot live without flickrRSS, at least ensure that caching is enabled. Other plugins or code that display your bookmarks at services such as Digg and del.icio.us can add time to your page loads as your blog attempts to contact each service. I know there is a del.icio.us plugin that has caching, so if you must display your del.icio.us bookmarks, have that enabled. Gravatars can also dramatically increase loading times on popular pages with many comments, but this is one of the things I deem vital and still have enabled on my site. Again, there is the WP-Cron Gravatar Cache plugin to help with loading times.

I have seen many people use more than one form of stat tracking; Mint, Measure Map, Google Analytics, Performancing Metrics and others. Each loads their own JavaScript file, so it is best to choose which one you like and only use that.

Images

This one should be obvious. The more images you have, especially ones not web-friendly, the more likely you are to drastically increase loading times. Images such as your header and footer should be as small as possible. When saving them in Photoshop, utilize the File » Save for Web dialog and save your images as a jpg or your favorite file format, at somewhere between 55-75% quality. Depending on whether your image has text or lots of detail, you can adjust the file quality accordingly. Something more than 50kB for a header image will start becoming burdensome. Take a look at the image maps section in Part 4 to deal with icons in your footer.

In addition to the main images, you can't forget about the smaller ones such as feed subscription images, social bookmarking icons and the icons that come with K2. Only use those which you cannot go without. I don't use any of the icons that come with K2, however they are still defined in style.css and still loaded, regardless of whether or not that CSS selector is ever called. Using display: none; on each CSS selector in your scheme isn't enough. You will have to manually edit your style.css file, commenting out each icon you don't wish to use. Remember what you did the next time you upgrade your K2.

Particularly, comment out the background attribute for .commentslink if you don't wish to use the comment icon, .chronodata for the time icon, .tagdata for the tag icon, .commentsrsslink for the RSS feed icon, .trackbacklink for the trackback arrow icon and .commentmetadata for the time icon (again). However, if you will still be using the pieces of K2 where the icons were displayed, you will want to adjust the padding for each so that there isn't an awkward gap. Each of these uses a line like padding:2px 0 2px 20px;. Add a line such as padding:2px 0 2px 0; to your scheme for each of the CSS selectors of which you aren't using its icon.

Also, if you are not using livesearch you will want to remove the three images that are called for livesearch in style.css. Comment out the background attributes for #LSResult, #searchcontrols and .LSRow:hover,#LSHighlight,#LSHighlight:hover.

If you are using an image for your background such as a gradient or a pattern for something, as I'm using for my main menu links, consider the size of those as well. For a background all you really need is a 1 pixel wide image that is as high as necessary and the repeat-x attribute. For example, if you want to make an image load in your #page and have it repeat vertically all you need is a 1 pixel high image. Your CSS will look something like this for that background image (this is what makes the shadow in my sidebar):

background: #fff url('defiance/sidebg.jpg') repeat-y left;

The original image I used for my main menu diagonal lines was over 200 pixels wide. I was able to open it in Photoshop, figure out how wide it needs to be to properly repeat and cut it down to around 20 pixels wide.

Compress Your CSS

With the default K2 style.css at over 19kB in addition to your own custom scheme, there is an easy way to save some time. Compressing your CSS with a tool such as CSS Tweak performs several things including removing whitespace and comments. With style.css, ela.css and your scheme there is a good amount of time to be saved.

For WordPress to properly recognize style.css, you will need to add this bit of text back to the top after you compress it.

/* Theme Name: K2 Theme URI: http://binarybonsai.com/wordpress/k2/ Description: The sequel in spirit to <a href="http://binarybonsai.com/kubrick/">Kubrick</a>. Developed by <a href="http://binarybonsai.com">Michael Heilemann</a> and <a href="http://chrisjdavis.org">Chris J. Davis</a>. Share and distribute. Version: Beta Two Author: Michael Heilemann & Chris J Davis Author URI: http://binarybonsai.com/ */

However, always keep a non-compressed copy of your current stylesheets. Editing a compressed CSS file isn't the most intuitive so I generally edit the non-compressed file, compress it and then upload it again.

Server Side Woes

Even if you have gone above and beyond optimizing your website with load times in mind, your server might not be as optimized. PHP rendering and fetching data from your MySQL database can take up to as much time as it takes for the browser to download everything, execute any JavaScript files and display the site. If possible, contact your webhost and ask for a PHP performance boosting server add-on such as Zend.

For MySQL, ensure you are running a stable version of MySQL 4.x and not stuck on MySQL 3.x. Some webhosts offer a MySQL optimization service to give your MySQL settings more cache, dramatically improving performance. There was a time when not even my server was able to handle a day of massive traffic, but increasing MySQL's cache helped dramatically and made my server near invincible.

If you are looking for a webhost with many of these features, take a look at Media Temple's upcoming (ss) version 6 and their high-performance (dv) line featuring Zend.

When talking about the database, there is also the discussion about plugins making superfluous database calls to be brought up. If you are running many plugins, be weary of ones that might call the database too frequently and crash your MySQL server upon massive traffic. After talking to Brian Benzinger from Solution Watch, I was told to stay away from the Bad Behavior spam plugin for WordPress which consistently killed the MySQL service, by making way too many database calls, on his (mt) (dv) server when under load.

Web Standards

By running clean, valid XHTML and CSS, your readers' browsers won't have to waste time guessing what you meant by that blurb of invalid code here and there. Using web standards also has other benefits, as explained by Roger Johansson. Check to see if your XHTML and CSS are valid.

Wrapping It Up

By taking these tips into consideration, I was able to take my website from 266kB down to 115kB. As I mentioned in the beginning, I use the website analyzer all the time. It is very convenient at tracking down what is taking so long to load. If I were to opt for a minimalist approach and not use header or footer images, I could probably get this site down to 70kB. For as many aesthetic tweaks you can do to help load times, there are just as many optimizations that can be done to the server. Get to know what software your server runs and find out what can be done to help you out. Increasing the memory limit for PHP in the /etc/php.ini file is a good way to start, but I would leave that and other server tweaks to your webhost.