Add more caching with (background) images

This week we are reviewing advanced techniques to speed up your website. Maybe some of them are really extreme but it’s even better – we don’t need to apply something more in the future. So we have used textual files merging (both JavaScript and CSS ones). Then we have moved to data:URI and reviewed few approached to use this technique on your website (both manual and automated ones).
Today we are speaking about moving some of your images to CSS. Why it’s important?
- With the help of data:URI and/or CSS Sprites we can significantly reduce number of HTTP requests which are required to load basic website template.
- This template is used (usually) through the whole website (or maybe one template per section) so it must be cached well. With CSS images it’s much easier (and such images are cached more aggressively than plain HTML ones).
- Also with such transformations (move design images to CSS) we reduce amount of HTML code served with each page to our visitors. This also helps a bit to increase load speed.
Detecting images
To start with such WordPress performance optimization we need to detect all images which can be safely moved to CSS rules. This can be performed with any web tool which is accurate enough to get all img objects from HTML page. In this manual we are using YSlow (the following table has been cut a bit to contain only URL and actual image size).

Small decorative images are usually less than 10 Kb in size and are located somewhere in template directory (not in WordPress uploads folder). Also they are static (not served with timthumb.php library). So from the table we can create our list of target images.
/wp-content/themes/basicpress/images/basicpress.png /wp-content/themes/basicpress/images/slider-selected.png /wp-content/themes/basicpress/images/rss_32.png /wp-content/themes/basicpress/images/email_32.png /wp-content/themes/basicpress/images/delicious_32.png /wp-content/themes/basicpress/images/stumbleupon_32.png /wp-content/themes/basicpress/images/twitter_32.png /wp-content/themes/basicpress/images/facebook_32.png /wp-content/themes/basicpress/images/linkedin_32.png
Not so much – 9 images. But 9 additional HTTP requests with page load.
Preparing styles to replace images
Here is the most interesting part of overall process. Before we replace images with their CSS equivalents we need to create these equivalents. How this can be performed?
Well, first of all we need to get size of an image (let’s start with the first one – basicpress.png). It’s 300px x 50px. Great. So let’s create proper CSS class for it (you can choose any name, in this example it’s img_basicpress).
.img_basicpress {
width: 300px;
height: 50px;
background: url(/wp-content/themes/basicpress/images/basicpress.png) no-repeat;
display: inline-block;
}The last rule is required not to break website layout, because images have width and height but displayed as linear elements. So they must have display: inline-block. To fix bad behavior under IE we should add
* html .img_basicpress {
display: inline;
zoom: 1;
}
*+html .img_basicpress {
display: inline;
zoom: 1;
}Both sets of rules just make our link or span element inline and add hasLayout property to it (this combination turns inline element to be shown as inline-block one in old IE).
Finally our piece of CSS code for 1 image will be the following
.img_basicpress {
width: 300px;
height: 50px;
display: inline-block;
background:url(/wp-content/themes/basicpress/images/basicpress.png) no-repeat;
}
* html .img_basicpress_png {
display: inline;
zoom: 1;
}
*+html .img_basicpress_png {
display: inline;
zoom: 1;
}Before further processing please prepare all such classes for your images. You can place them (better) to the end of CSS file or (worse) to the website template. If you are using some CSS auto merging solution (such as WEBO Site SpeedUp).
Actual replace
OK. Now we have all data prepared to the last step and we are going to replace of HTML images with their CSS-twins. This operation can be a bit boring but it worth! So let’s start with our logo image – basicpress.png. We need to find in our template folder (for this case it’s wp-content/themes/basicpress/) file with such image(s) and replace HTML code with the new one. Basicpress logo is located in header.php – so we just need to replace
<a href="<?php bloginfo('url'); ?>">
<img src="<?php bloginfo( 'template_directory' ); ?>/images/basicpress.png" border="0" />
</a>with
<a href="<?php bloginfo('url'); ?>" class="img_basicpress"></a>Please note: we have completely removed img element and added class img_basicpress_png. If there is no class on this element – you need to add it.
In case of raw images (without parent a element) please replace img tag with following construction
<span class="img_basicpress_png"></a>
Also please don’t forget to move title attribute from img to its replacement (a or span).
So according to this set of rules this code
<img class="arr-selected" src="<?php bloginfo('template_directory'); ?>/images/slider-selected.png" border="0" />must be replaced with
<span class="arr-selected imd_slider_selected_png"></span>
But the last change has broken our slider with 3 last articles. Arrh. It seems after this change we need to add some fixes to our JavaScript code. So let’s go to wp-content/themes/basicpress/header.php and find there string
$('img.arr-selected').css('top',$(this).find('span.arr').html() + 'px');as you can see it relates to img which is absent now. We need to replace it with
$('.arr-selected').css('top',$(this).find('span.arr').html() + 'px');which is faster in modern browser (direct call to getElementsByClassName).
Complete tracing of such situations can be a bit boring so after every change we should check our website layout – and be sure that modifications have gone well. If no – we can roll back all changes.
After we have performed all described actions for our social icons (in the sidebar) we have a bit better chart.

If you compare this one with the previous one you can see that there are minus 10 HTTP requests and actually no change in website size. Congratulations – we finally have achieved what we wanted.
Alternative approach
There is an alternative approach (which is much safer because we leave img tags in the document). But it requires one additional image (actually 1×1 transparent gif) which is placed instead of current images with proper background and dimensions. This approach is also used to prepare HTML Sprites (we will cover WordPress plugin cSprites in one of the next posts) but you can see live demonstration on Aptimize website. The last one uses with technique in its solution (sorry, it seems no real one for WordPress on a shared hosting).
Our first technique (with inline-block styles) is better in terms of HTML semantics but can cause different troubles. SO consider all ways to improve your website load speed during its web performance optimization.
Conclusion
Simple CSS images replacement reduces total number of HTTP requests by 10 (or about 200ms for our website, 4 more per cent). And this has led to no data size increase (images have been turned into base64-encoded ones) which makes such approach almost perfect (possible drawbacks have been discussed above).
NO RESPONSE TO Add more caching with (background) images