Perf-ecto kinda

I was able to get pretty great performance with only a handful of updates to my site, thanks to Smashing Magazine and a little effort. Here's how I did it.

By on

After reading Smashing Magazine’s performance case study I became obsessed with improving performance on dBlogIt. I am often concerned with performance, but I hadn’t reviewed the state of affairs since moving back over to Jekyll on Dreamhost. dBlogIt wasn’t happy.

Just like Smashing Magazine, I had done a few things right, but there was a little “good old-fashioned website decay,” mostly in terms of link-rot. But I had also skimped on some basic stuff too.

For example: I was running ModPageSpeed and it was doing fine, but it seemed to be doing things I should have done to begin with; I had a whole slew of optimizations in my .htaccess file like compression, and caching, but they were mostly copypasta that seemed verbose and overly complicated; my CSS was pretty clean and reusable, but it wasn’t being compressed; I was using a bunch of fonts and they were blocking the page while it was loading.

Question everything

It was important for me to make sure that every part of the site was serving a purpose. So the first order of business was to rethink, refactor, or remove anything that might possibly be slowing things down or mucking things up.

I started by completely disabling ModPageSpeed and commenting out all 80 billion lines in my .htaccess file, including around 800 redirects (to make sure they weren’t slowing the site down too much). Then I headed over to WebPageTest to get a nice baseline.

Focus on the Critical Path

There are two key performance goals in the Smashing article that I thought I’d shoot for:

In other words, load the page in under a second, like Nielsen said, and do it by getting all the assets into the first 14 KB, which is the “first package exchanged between a server and client via towers on a cellular connection,” according to Google.

To hit my goal I would need to identify the critical components that needed to load right away. For me that was a sampling of blog posts, including at least an excerpt of the latest one, and links to the most recent ones; the logo, as I’ve worked very hard to keep that consistent over the years; and the font, because it reflects my own personal brand. Everything else could wait.

I had a sweet little logo-font that I made from scratch years ago. I’m quite proud of it, even though it had some kerning issues. But it was a few kilobytes and a request that I didn’t want to make. So I decided to treat it like content, and embed it as an SVG image.

The styles

The stylesheet for dBlogIt is basically a modified version of Normalize that I ported to SASS. That is to say that there really isn’t much to it. When minified, the file is around 5 KB, and every bit of it is used on every single page of the site. By inlining the compressed file I removed another request from the page.

The index

The home page is usually the most visited page of any website. dBlogIt is no exception to that rule, so it was important that it be as light and fast as possible.

Previously I was displaying the latest 10 posts, in full. That put me over the 14 KB max size that I was shooting for (even compressed). The index needed to be redesigned.

One option was to show a list of all the posts I’ve ever written, but that would put me over my size budget; Another option was to show full posts, but limit the number to five or one. That didn’t seem as if it would meet the reader’s needs (in my mind). If I were a visitor to my own site, I reasoned, I would want to see an excerpt of the latest post (so I could decide if I wanted to read it), and a list of maybe 10 of the most recent posts, just to make sure I hadn’t missed anything. This approach also turned out to be more friendly to my max file size.

The fonts

I was using six fonts—five after ditching the logo-font for SVG. That left me with one icon font and four font styles for the copy— PT Sans regular, bold, italic, and bold-italic. The icon font, from Ico Moon, was only a few kilobytes so I decided to leave it and focus on the other fonts.

I used the exact same approach that Smashing used: base64-encode each font and inline them into a separate stylesheet, then load those styles into localStorage with a little JavaScript in the head (to avoid FOUT). Et voila! One request for all the fonts, and zero requests for fonts on subsequent loads.

Compression and caching

Now that I had the critical path sorted, I needed to re-enable some of the server-side optimizations I had in the .htaccess file. I wanted to ensure that everything I added was well thought out.

The best resource I know in that department is the HTML5 Boilerplate Apache Server Configs project. I just grabbed the whole pre-built .htaccess file and went line-by-line enabling and disabling items until I was satisfied with the result. I added back my redirects so that the old links would still work, I then updated the expires time on text/html files to one hour instead of zero.

Caching everything had one downside: any updated stylesheets wouldn’t be immediately retrieved by the browser. I had to introduce an asset pipeline into my Jekyll setup in order to bust the cache when a file changed, but I’ll save that for another post.

The results

A quick trip over to WebPageTest revealed that I had not only met my goals, but far exceeded them. The speed index averaged in at 403, and the home page weighed in a miniscule 6.8 KB! I’d call that a success!

What’s next

There’s still a bunch of work that can be done in the font department, including inlining the icons with SVG and removing the bold-italic font altogether (I rarely use both bold and italic together so it’s a great candidate for the chopping block). Those two changes would make the fonts CSS file about 30 KB lighter.

It might also be fun to use JavaScript to pull in recent and related posts instead of having Jekyll generate them, but that would be kind of a micro-optimization that is hard to justify in terms of performance. Especially when I have so many broken links and images throughout the site that really need some attention.