Speed Optimization for every website
Is your website too slow? Learn how to make your site blazing fast with interactive, step-by-step help.
The need for speed
Thank you for wanting to make your website more efficient. An increase in performance not only makes your users happier, but it has been proven to increase sales/actions. On top of that, you're being green by saving bandwidth throughout the internet and power on devices browsing it. Win-win!
The lifecycle of a page load
Before we can optimize our site, we have to understand how it loads. From there we can identify bottlenecks and work on speeding those up to lower our overall load time.
The best way to illustrate how your page loads is with a waterfall chart. These can be seen by running tests on your site through tools like WebPageTest.org, or simply using the 'developer tools' feature of your browser. Not only do they time the page load for you, but they'll break down every element that gets loaded so you can easily identify what's making your site slow.
Let's take a quick look at a waterfall generated by loading Amazon.com's home page in developer tools on Chrome:
According to this chart, it took about 2 seconds to load 74 resources. That's pretty good (we'd hope Amazon's home page is optimized). Each resource's load time is divided up into several stages, such as DNS lookup, initial connection, time to first byte, and content download. By looking at each of these resources (and which stages for each), we can figure out what we need to optimize.
Here's the same page ran through WebPageTest's tool. Looks pretty similar, huh? Both of these tools have slight differences which make them more convenient in certain situations, but overall they should show about the same results.
What's neat about WebPageTest is results are saved so you can link to them if you want to share a result with someone else on your team. Here's a live view of the result above.
Spend some time getting to know the waterfall chart - it will become your best friend when diagnosing performance issues. Run a few tests of your own right now. Compare a fast site with a slow site to see patterns on what makes things fast (hint: less resources, CDNs, and minimized resources, to name a few). Here's a more detailed walkthrough on Chrome's Dev Tools, and using WebPageTest, whichever you prefer.
Identifying the most efficient optimization
There are many ways to speed up your site, and they can grouped into three categories: Back-End Optimization, Front-End Optimization, and Network Optimization.
Most web developers will first focus on speeding up the back-end (ie, code ran on the server), although that's usually not the best approach. Take a look at our waterfall chart example again:
The very first request is getting the html document from the server, ie the back-end. Notice how it's only 271ms of the entire page load of 2.02s. That's only about 10%!
In this example, if you speed up the backend by a factor of 2 you only bring your page load down ~5% to 1.88s, yet if you speed up the front-end (and it's associated network) you cut it down ~40% to 1.15s - that's way more effective!
Also keep in mind that optimizing the back-end is harder to do than the front-end. Optimizing server-side code and databases usually requires changing way more than moving a few things around in the HTML.
I hope I've convinced you not to focus on back-end performance first. Yet sometimes your first request is so slow you risk your users abandoning the site before even seeing anything.
Here are a few tips to increase your back-end performance:
- Server hardware - Check to make sure you're not using all your allocated CPU or memory. On a shared server you should be able to see your usage using tools within your portal, example here. If you're nearing your limits, see if an upgrade to the next level plan would help. If you're on dedicated/vps/cloud, consider allocating more cpu cores, memory, or switching to solid state drives.
- HTTP Server Software - Most web servers use Apache by default, yet there are other variations that provide higher performance, such as nginx or lighttpd. On a shared server you're usually stuck with what they offer, so it may pay to shop around. On a dedicated/vps/cloud you have control to use whatever http server meets your needs.
- Database Tuning - Make sure your queries are utilizing indexes, checking with a tool such as MySQL's EXPLAIN. Also consider what database engine you're using (on MySQL, there are vast performance differences between InnoDb and MyISAM). On a dedicated/vps/cloud server be sure to play around with your database settings until you've configured your environment optimally. Here's a good primer for MySQL.
- Server Caching - Every time a page is requested your server is generating its content. If some of your pages are static and don't depend on user input, consider a backend cache that will save the page in memory (or disk) so the next time it's requested it can be sent immediately instead of re-processed. On a shared server you usually don't have this luxury, although you can mimic it in Wordpress using a caching plugin (highly worth it since Wordpress themes/plugins can be a beast).
- Code Optimization - Take a look at your server-side code and analyze your algorithms. Could a different approach reduce the computation that's needed? Ensure there are no unnecessary processes. For example, it's usually quicker to have your database sort your results than to return all results and sort them within your app.
- Load Balancing - If your servers are very busy handling lots of traffic, they'll slow down. Consider duplicating your content on multiple servers and placing a reverse-proxy server in front to balance the load equally.
Considering that most of the load time is spent requesting resources, you'll probably get the biggest bang for your buck here.
- Make fewer HTTP requests
- Put stylesheets at the top
- Minify your images - PNGs for small icons, JPGs for pictures
- Reconsider your frameworks/libraries - Bootstrap CSS is almost 200KB, jQuery is around 250KB. Do you really need the full jQuery library if you're just using a few functions? Consider the page you're on right now, which is using PicniCSS (~30KB) while still being responsive and looking (fairly) decent.
Yahoo has a comprehensive guide with 35 best practices for front-end performance.
Web performance guru Steve Souders (formerly of Yahoo) has a couple great books that dive into these issues further. Check them out on Amazon: High Performance Web Sites, and Even Faster Web Sites
Steve's tool Cuzillion demonstrates the effects of arranging your css, js, and other resources in specific order, showing how some types of elements blocks others from being loaded.
Every single resource on your page has to be transmitted over the wire (or air) to the user through the network. Since this can happen hundreds of times per page load, small improvements here will have a great effect overall.
- DNS Provider - While DNS looksups are often overlooked, it's a super simple way to gain an extra 100ms on new requests. Check SolveDns, which tests and compares DNS providers so you can find the fastest
- Enabling compression - It's much quicker to compress a file, send it over the wire, and then uncompress it than to send the original file over the wire. Check your headers to see if gzip is enabled, and if not ask your host to switch it on (or enable for yourself if you're able to)
- Caching - Upon first load this isn't going to help much, but if your visitors experience more than a single page on your website, it's worth it to set your caching headers so browsers know they don't need to re-request something that hasn't changed. Learn more here
- Use a CDN - Most of the content that's pulled from your server is static, ie images, js, and css that doesn't need a backend to process it. So why not give your server a rest and let it deal with the complicated stuff while letting a CDN (content delivery network) serve the static stuff. Not only do most CDN's have "edges" that are closer to the user requesting the content, but you'll also be cutting down on your request headers, which use up client upload bandwidth. Another reason to use a CDN is because some browsers limit how many connections they open per host, so if you spread out your content via mutliple hosts you'll be able to increase downloads happening at the same time.
- Is HTTPS needed? The HTTPS protocol requires an extra layer of connection handshaking, plus additional encryption/decryption on both the server and client. I'm all for a secure internet, but do you really need to server your CSS files over HTTPS? Serve private content over HTTPS, and public content over HTTP.
- Major Hub Transmission - This is the time spent sending files between your user's ISP and your server location. Most hosts will have strategically located their datacenters in popular internet hubs in order to streamline this communication. In the US, here are examples of major cities that are well-equipped internet hubs: Los Angeles, Dallas, New York, San Diego, Seattle, Ashburn (VA). This map shows all major US cities you should hope your host is near.
- Last Mile Transmission - From the major hub to your user's house is something out of your control. They may be on an almost-instantaneous Google Fiber set up, or be as archaic as a dial-up modem. Because there's nothing you can do to control this speed, the best strategy is to reduce requests and file sizes.
I'm adding a 4th category of optimization, perception, although it's not going to affect the load time of your site. It will affect how fast your users perceive your site to be - which is just as important.
Screens are almost always smaller than the entire website being rendered. When this web page first loaded, you only saw the top 10% of it within your screen, while the rest below it was still being downloaded. This is the concept of the website fold. Try and optimize as much as you can above the fold, which will give the user the impression that the website is done loading even though part out of view are still being processed.
Another set of techniques involves using quickly-loading placeholders until the real, slower-loading content is generated (and then swap it out once it's ready). These placeholder can be as simple as colored boxes, or as realistic-looking as animated gifs, but either way it will make the user feel like the page has loaded quicker than it really has. The bare minumum of this technique is assigning heights and widths on your elements so the page doesn't have to be redrawn/reflowed as content is gathered. This great article shows impressive examples.
You can measure the speed index of any site through WebPageTest as long as the 'capture video' option is selected. Learn more about the speed index.
Fixing and monitoring your optimizations
One thing you've probably noticed as you're testing your website is that performance can vary quite a bit between tests. One day may seem fine, while another super slow. From the US may be lightning fast, while from Europe it's barely crawling. Desktop is rapid, but from mobile it's 1990 all over again. Sometimes multiple waterfall tests in a row will even provide drastically different results. It's important to keep measuring your website examining all these variances.
Consider using a tool that runs these tests at specific intervals from differing environments and keeps track of the results so you can see trends. You may find that attempting to optimize your database was a bad move, while switching to a CDN was one that has proven increases. MachMetrics is a pretty useful tool that automates this process.
Thanks for taking an interest in improving your site's performance, and thus the internet as a whole. Be sure to check out the interactive demo as well as some helpful tools.