Making our website fast
December 19, 2014
What is “fast enough”?
For some time I’ve been intrigued by what makes a website or application performant. I’ll spend hours optimizing code, combining and minifying scripts, cleaning out CSS, eliminating requests, tweaking .htaccess files, shrinking image files and testing over and over on webpagetest.org. Maybe it’s because I don’t play video games. This is my game of website optimization. I want the fastest site, and no site is ever fast enough.
Google’s Paul Irish has claimed (now quite famously) that the optimal page speed measurement is a PageSpeed Index of <1000. His comment on Tim Kadlec’s blog has taken on a life of it’s own. Like Trent Walton I’ve begun to reference back to this comment frequently. I’ve watched his Fluent talk about page speed at least 10 times. It’s fascinating. It’s the modern science of web development, directly impacting user experiences and the success of a website. I could optimize sites all day long probably (with enough coffee).
Page Speed Matters
The time it takes to load a webpage directly affects the success of that page and the website as a whole. This has been shown numerous times, and as we continue to see ever greater mobile use it becomes even more important. Tammy Everts has a great article about how to calculate exactly the cost of a website that doesn’t perform. Users reward faster sites by using them more. That’s the bottomline really. But even before someone uses your site, they have to find it. Since Google rolled out their new Mobile-friendly indication on search results, page speed has started to play a more direct roll in SEO. One of the metrics Google is using to determine the mobile-friendliness of a website, is speed. So it matters a great deal for users and for search results.
To make a website fast
This is the tricky part. There is no single answer. It stems from a variety of factors, each of which needs to be considered in the context of all the others. The greatest tool at our disposal is Pat Meenan‘s amazing and wonderful WebPageTest.org. It’s a great way to gauge a website’s performance and find bottlenecks in your page load time. What we did was a series of optimizations to decrease the number of requests, reduce file sizes, and speed up initial DOM rendering time to increase the perception of speed. I’ll outline below each piece we addressed and give just a quick overview of how and why. My list of optimizations is based on the articles above, Dave’s great post on eliminating RWD bloat and my own past experiences and experiments.
What we did to make our website fast
- Optimized Images – this is a no brainer. All your images on a website should be optimized. We adjust the overall size of them to best fit the largest that they may ever be used. Then we use a series of tools to make the image file smaller. One of the easiest and most effective tools to shrink image files is ImageOptim for Mac. It’s awesome.
- LazyLoad Images – We used Mike Tuupola’s LazyLoad script for dynamically replacing images either as img tags or backgrounds when they scroll into view. It’s simple, small and works great. We chose to use a lower res version of the same image as the default, instead of a background color gif. This increased our overall page size, but the speed loss was worth it to us in this case for the improved user experience.
- Critical CSS Inlined – This was a daunting task to me previously, until I found Addy’s Critical tool and the complementary Grunt-Critical. It’s great. It works mostly out of the box, requiring just a little bit of manual adjustment to remove font-face, etc. I’m sure I could optimize my use of it, but for now I run it on demand when I’m ready and copy the results into the head of my html.
- Lazy Load CSS – Once you have your critical CSS inlined, it’s time to move the rest of the CSS styles down the priority list a bit and load them in later. This does produce some flashing, which can be minimized with a little effort and adjustment. But Filament’s LoadCSS does wonders to load your css and font-face files.
- Move Scripts to Footer – Now we make sure all our unnecessary scripts are included at the bottom of the page. In WordPress this can be a bit tricky. It sometimes requires manually dequeueing some plugin scripts and re-queueing them appropriately. We chose to be careful, but do what was best for our site. We had to do some manual tricks here and test a lot, but we got all the scripts out of the head of the website, except for GA. Look out particularly for jQuery on WordPress. We had to manually address this separately due to other scripts relying on it and how WP Core handles loading jQuery.
- Minify stuff – I already use a custom Grunt file that combines and minifies my CSS for me. Sometimes I even use it to evaluate the rendered html, find all the unused css selectors and remove them. This helps a great deal, but we didn’t do it on this site, yet. It’s a little more of a manual process for a WordPress site and we already felt the site was fast-enough. Still we minify all our CSS, JS and even the HTML just for fun. Why not. It’s easy and helps a little.
- .htaccess Cache & Compression – This one helps a bunch. I have my own custom .htaccess file that I like to use which is essentially a fork of the html5boilerplate one. It works well for both flat file sites and WordPress. The major features to include are caching limits and compression. Those two configurations will greatly improve your site performance.
- PHP Caching – This makes a gigantic difference to improve Time to First Byte for WordPress sites. You must do it. I’ve hardly ever run into a case where it isn’t beneficial. I’ve tried quite a few plugins for this, and some of my own custom configs, but these days the W3 TotalCache is the best. It’s so great right out of the box. But we configure it a bit to take our other optimizations into account. It dropped our TTFB from over 1s to .222s. Hot tip – to really get a sense of how fast it is, make sure after you set it up that you visit the site from another browser so that the page cache is created, then run your webpagetest.
That’s most of it at least. It takes time. Optimization is part science and part a game. It’s a matter of making adjustments, testing them, adjusting again and testing again until you get it right. Some of these things can seriously mess with the functionality of your site as well, so look out. You’ll have to constantly keep at eye out to make sure you styling is still correct and UI is fully functional. That’s the fun part for me though.
So, how did we do? Well our site wasn’t horribly slow to begin with, but it needed to be faster.
Initial PageSpeed Index: 2602
While that’s well over the 1000 benchmark, it’s not crazy. But our time to start rendering was nearly 2s. That’s 2 full seconds of waiting until anything at all appears on the screen. And preceived speed is almost as good as real speed. So getting the DOM to paint more quickly was a secondary goal. After applying all the changes listed above we were able to make our site fast-enough for now.
Final PageSpeed Index: 967 !!
That final index correlated with a start render time of .488s, which is 1.5 seconds faster than before! A 75% improvement in perceived page speed is no small feat. Granted our page size may have actually increased on the home page due to using low-res images as initial images instead of just a small background gif placeholder. But, even with the additional page weight of those images, our site is still faster. I’m truly happy with the results. There is still a bit of FOUC to handle, which is an issue with lazy loading the custom font files and stylesheet, but it’s minimal and could be argued the flash plays into the perception of speed. Our website is fast-enough now.
Do you need help optimizing your site? We’d be happy to take a look under the hood and see what we can do.
Shoot us an email anytime. firstname.lastname@example.org or find me on twitter at @abaumer.
Do you have any of your own techniques to share?
I’d love to learn more about how you optimize or why it matters to you. Post a comment below.