🚀 See the 2024 Ruby on Rails Community Survey results!
Article  |  UX

Improving performance with the modern website tune-up

Reading time: ~ 6 minutes


Your website, just like your car, is often due for a bit of maintenance. Fortunately, tuning up your website is less intimidating than that familiar experience of standing next to your vehicle, nodding your head dumbly while handing your mechanic (who, by the way, is much more ruggedly handsome than you) a wad of cash. And that is even less daunting than attempting to work on the car yourself- you’ve tried that before, and you still have nightmares and stained pants.

Sometimes you need that extra push to prompt you to invest in your car – perhaps it’s that nagging friend, or that nagging muffler scraping along the ground. For us, the push to spend some time improving our site’s performance was analytics. Our interaction designer Annie has been paying a lot of attention to analytics- both to benefit our clients’ sites, as well as our own. We’ve improved our methods of observing user activity on planetargon.com, and we’ve learned a lot about what works and what doesn’t. Using Google Analytics, we’ve also been able to see that a few pages were loading particularly slowly. Armed with the average load times, bounces rates, and exit percentages for every page on our site, we set out to speed up load time for the slow pages, as well as the rest of the site, in hopes of improving user experience.

So join me, will you, on this journey through website optimization and mixed metaphors. One caveat: I don’t know shit about cars, so my comparisons to timing belts and piston rings will at best be illogical but well-intentioned; at worst, my advice could cause harm to you or your car. Please consult with a trained mechanic before trying to reduce drag or shave off unnecessary bits from the chassis.

Let’s assess the damage

Just as the mechanic might plug in an inspection device to analyze the health of your car, it’s helpful to use a tool to probe the well-being of your website. I found both the YSlow and PageSpeed Chrome extensions to be invaluable. The YSlow approach seems to be to chastise the user (“Grade: F”), perhaps utilizing a shame-is-the-best-motivation strategy, while PageSpeed was definitely raised by granola-munching liberals (“There are no high priority suggestions for this site. Good job!”). Actually, they’re both fantastic at offering a comprehensive list of performance suggestions; PageSpeed even creates minified/optimized content for you to drop right into your project. Based on the results of the performance audits made by these two tools (especially HTTP requests and total page weight, both found under YSlow’s Statistics tab), as well as average load times gathered from Google Analytics, I was able to come up with a list of priorities and action items. I even made a spreadsheet!

First: Optimize images


This is sort of like replacing those heavy carbon alloy and glass doors for something lighter, like, say, cardboard… or better yet, garbage bags! Actually, cutting down on image file size is probably the most significant way you can reduce your overall page weight. At first, I just tried running the entire image directory for planetargon.com through ImageOptim, which I thought would be an extremely quick way to shave off hundred of kilobytes. Unfortunately, this didn’t yield the impressive results that I was hoping for.

I tried Smush.it, a similar service, but the outcome was comparably disappointing. Upon closer examination, I noticed that we were using the PNG format quite a bit. This lossless image type looks lovely and rich but, unfortunately, that fidelity comes at the expense of file size. By bringing these PNGs into Photoshop, optimizing them, and saving them out as JPGs, I was able to reduce the heft of these images quite a bit; a photo that was previously 120kb was now 35kb, and the difference in quality is indiscernible to the naked eye. Again, I opened up ImageOptim- this time, after dropping in my freshly minted set of JPGs, the results were much more profound. Our Projects page, previously filled with higher quality but bloated PNGs, dropped from a whopping 2816kb to a markedly slimmer 1338kb- not ideal quite yet, but much better.

Second: Minify CSS


Five separate seat-belts? So much superfluous nylon! Wouldn’t it be so much more elegant and compact to just tie everyone together using one long rope? That, my friend, is minification. We use the SASS CSS-preprocessing language in conjunction with Guard, a Ruby gem that compiles and validates SASS stylesheets, so the switch to outputting minified CSS was merely a matter of adding the :style => :compressed option to the Guardfile. This change alone reduced our primary CSS file from 115kb to 83kb, and our mobile stylesheet from 25kb to 17kb.

Third: Reduce HTTP requests

“Several short trips taken from a cold start can use twice as much fuel as a longer multipurpose trip covering the same distance when the engine is warm,” instructs fueleconomy.gov. Ever found yourself driving to the store to buy some toothpaste, and then, upon arriving home, remembering that you don’t in fact have a toothbrush? Out you go, wasting more time and gas. Now, in the comfort of your home once again, the realization strikes- wait a minute, you don’t have any teeth! Out you go, this time to pick up your trusted denture cream. Those excessive trips to the store affect your mood, your wallet, and your schedule, just like extra HTTP requests adversely affect the visitors to your website.

Utilize image sprites

The idea is this: combine a number of background images into one large image, use CSS to specify your targets, and voila- you’ve reduced HTTP requests from three or thirty or three hundred to just one. There are a bunch of services out there that, in one way or another, are supposed to make the creation and implementation of CSS sprites as effortless as possible. I tried both SpriteCow and SpriteMe, 2 such services, and found them interesting, but in the end I opted for creating my own. SpriteMe generated a sprite with a generous amount of extra space, and stacked them vertically, even though all the images were the same height. In my tenure as a front-end developer, I’ve made dozens of CSS sprites, so I found it a bit frustrating to relinquish control to one of these services. There is indeed some tedium involved in generating and using CSS sprites, however, so I think it’d be worth exploring these apps a bit more.

Concatenate JS and CSS

I knew that we were using a utility for one of our client projects that packaged up separate javascript and CSS files upon deployment, and I wanted to take advantage of this feature for our site as well. In its own words, Jammit provides “both the CSS and JavaScript concatenation and compression that you’d expect, as well as YUI Compressor, Closure Compiler, and UglifyJS compatibility, ahead-of-time gzipping, built-in JavaScript template support, and optional Data-URI / MHTML image and font embedding,” but it was really just the concatenation that I wanted. It was unfortunately a bit more complicated than I’d hoped to find the version of the gem that best suited our install of Rails, and I wasn’t able to enable JS minification, but I eventually came out the other side with nicely packaged javascripts and stylesheets. I also took this opportunity to go through all of the jQuery plugins and libraries that we were loading, remove those that weren’t being used anymore, and narrow the scope of the ones that were- Jammit made it easy to load only those specific javascript and CSS bundles that were needed for each page.

Fourth: GZip/Deflate HTML/CSS/JS


You know what would make that tank of yours much more fuel efficient? Keep all the important parts (driving wheel, cigarette lighter, Betamax player, engine, etc ) but get rid of the bulk… you know, just compress it a bit. Both YSlow and PageSpeed reported that our users would be able to enjoy significantly reduced response times if we enabled compression. This was another easy one to implement: we added a line to our Apache config file (“AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-javascript text/css”), which tells the server to send over compressed HTML, CSS, and JS if the user’s browser is capable of handling it. A request to send over our main stylesheet now only results in an exchange of 18kb, rather than the 102kb it previously required!

The Results

Before:

After:

Just as I think PageSpeed might be a bit too flattering, YSlow is depressingly critical. A typical page on planetargon.com went from a PageSpeed of 90% before the changes to 92% after, while the YSlow result went from a D to a C… reminds me of school all over again.

To be continued…

I’d say we made some meaningful improvements, but there’s always more work to be done. Please share performance suggestions as well as resources (there are tons of them out there- I found the Yahoo and Google developer sites to be enormously convenient) that you’ve found helpful. This is a big topic, and it’s quite easy to lose hours down the rabbit hole of byte-trimming; but the result will be a more compelling and responsive experience for your visitors. We web professionals might not have the strong hands and chiseled jaws of our mechanic friends, but, like our greasier counterparts, we’re responsible for providing the means to an enjoyable and reliable journey.

Have a project that needs help?