Site optimization is important and if you're reading this post, I assume we're on the same page with why. I won't tell you that faster sites see more traffic, conversions, and overall engagement. Or that they rank better in search results. Or that it makes for a better experience overall.
(Nevermind, I just told you anyway.)
Instead, here's a 95%-of-the-way-there guide to optimizing your site for speed and performance.
It's 95% because I've focused on the free and mostly-not-technical things that will solve the majority of your challenges. If you need more technical solutions past this guide, then there's something significant that needs unique attention and an off-the-shelf guide probably can't help you. But I can guarantee that this will solve almost every major problem you have. Especially if you're using Wordpress.
- Testing your site's speed
- What causes performance issues?
- Getting to 80%: Fixing Images
- Getting to 90%: Scripts, Fonts, Cruff Code
- Getting to 95%: CDNs, Caching, Preloading
- Getting to 96%: Bonus on live chat tools
Let's get started!
Testing Your Site's Speed
There are a few ways to test site speed and performance:
3rd Party Tools
- Pingdom will run a rudimentary but complete speed test on any url you provide
- GTMetrix will run a 3-pass test (and have a slightly less friendly UI). A 3-pass test will help to average out temperamental differences in your server, browser, or testing suite.
You can run your own tests via your browser's "Inspect"/"Dev Tools" mode. In almost every browser, you can right click anywhere on a page and select the
Inspect Element option, or go to the menu and select Develop/Developer and open the
Web Inspector mode (different browsers use different names):
- Chrome Menu:
- Chrome Right-click:
The first test to run is in the
Network tab in your Dev Tools. Make sure to disable cache when you test, and then refresh the page to run the test.
If you're working with Chrome, you can also use the
Lighthouse tab for a more in-depth test:
Select all of them and test on mobile for the best report.
What Causes Performance Issues?
The biggest site speed/performance offenders on sites tend to be:
... in that order. The reasons are:
These tend to be loaded in too big and make the page heavy. If you're downloading a lot of files, you'll slow down the page.
Similarly, fonts are a problem when they are loaded in unnecessarily... which happens much more often than you think.
This essentially means that you don't take advantage of your browser's and server's memory to make things load faster.
Past that, you're likely looking at deeply technical issues that can't be solved with a standard guide.
Getting to 80%: Fixing Images
Images are easily the number one item that create problems for websites.
A web-friendly image should be in the range of 50-150kb, max. But most people load in images that are way bigger. I've noticed that people who use content management systems also tend to upload multiple versions of the same image, rather than reusing the first version. They also load in physically bigger images than necessary.
For example, I recently did a site audit for a good friend and images jumped out as the number one issue: he was loading in images that were 3mb at the largest, 200-700kb at smaller sizes. That's way too big! 6mb of his 7mb page size ended up being unoptimized images.
So, what can be done?
Glad you asked. There are a few things to do for image optimization:
- Sizing images correctly
- Compressing images
- Lazy-loading images
- Loading retina images for retina screens
Sizing images means not bringing in images that are way bigger than they need to be. Going back to my friend's example for a moment:
The first number (255 x 255) is the size that the image shows up as on the page. The second number (intrinsic: 3386 x 3386) is the actual size of the image. There is no reason this image should be 3k x 3k pixels if it is being loaded in only at 255 x 255!
There's sometimes a good reason why you may want to have a bigger-than average image. For example, sometimes when you have a responsive website design, what shows up as a small images taking up one-fifth of the page on desktop may end up being a full-width image on mobile, and the mobile image will counter-inuitively need to be bigger than that desktop image. (And if you have the technical chops, set up your code to load in different images per breakpoint; most people will only see your site on one website size so you want to optimize for the most common viewports.)
In brief: make sure to test the images at your correct mobile breakpoints and never load in images 2x the size of what they should be, at most.
Why 2x? Because retina screens (i.e, iphones, new android phones) have a high pixel density -- meaning that for an image to look "crisp" it needs to be loaded in at exactly 2x size. Learn more here, I won't bore you with technical details: https://premium.wpmudev.org/blog/make-images-retina-ready/
The second major image-related issue is compression: most images have a bunch of unnecessary information such as metadata, backup color-spaces, file instructions, and layers that add weight to an image without adding end-viewer value. So by removing excess data (and consolidating very-similar-pixels i.e., #000000 and #000001 into just one color), you can drastically bring down image size without losing quality.
There are a lot of image optimization tools. Some – like ImageMagik – run from the command line and form the backbone of other image optimization services. Others have a friendly drag-and-drop UI. Because this is a mostly non-technical guide, my recommendation is to use ShortPixel to optimize every image on your site (you can also download a WordPress plugin to automatically do this for every image, if you're using WordPress).
There are 3 levels of compression that most off-the-shelf tools will offer:
Lossless (only metadata is removed);
Glossy (some visual compression, but not enough to make a visual difference), and
Lossy (smallest file sizes, but you start to notice visual differences and pixelation). My recommendation is to use Glossy compression because you'll be able to get 60-80% smaller files, without any noticeable loss in quality.
Optimizing Image Loading (Technical)
For particularly adventurous optimizers, you can also look into Lazy-Loading images: loading an image only when you scroll over it, or come near it while scrolling, rather than loading every single image in from the start.
This has a lot of value on image-heavy and 'long' pages. I've used lazy-loading to start loading in images when they are 500 pixels below the fold, and continue this as people scroll down a page. It means you're continually loading files as you scroll, but it creates the perception of fast first-load times because you're only loading in the things someone sees when they first look at your page.
While there are some plugins for this depending on the site you use, it does require a bit more technical know-how, so I'll leave it for you to do some research on this if it is something you're interested in.
And remember what I said about retina-sized images? You can use
retina.js to ensure you're loading in @2x size images only when needed. Again, this is slightly more technical, but easy enough to implement.
In summary: size images correctly, save them in sRGB colorspace at 72dpi, and make sure to optimize them -- you'll be 95% there to a faster site.
Side note - Wordpress tends to do their own image compression, which I've found problematic at best, bad at worst. I recommend turning off wordpress's native optimizations, which will ruin your image quality. Quick google search (i.e., https://www.narga.net/how-to-disable-image-compression-in-wordpress/) will tell you how.
Getting to 90%: Scripts, Fonts, and Cruff Code
Before jumping in here, I want to reiterate that if you handle images correctly, you're 80% of the way there to a faster site. This is the next 10% is a bit more technical.
Wordpress is pretty notorious for loading in a lot of cruff code - the visual composer plugin, for example, can slow your site down significantly by loading in a lot of 'just in case' code. So my recommendation is to try out autoptimize as an optimizing plugin. It has a lot of flexibility -- I've used it extensively in deferring script loading and organizing code to speed things up.
Wordpress plugins are also pretty bad: for the most part, you want to use as few plugins as possible. Most of them are poorly written and will add a lot of unnecessary (or duplicated) code. There are a few plugins that are "okay" -- i.e., anything backend specific like Redis-cache and ShortPixel (see below for redis) that don't affect the front end experience. But others, like social share buttons, will really slow your site down by loading in a lot of tracking pixels, spamware, and simply bad, heavy code.
Render Blocking Scripts & Deferred Script Loading
The biggest things to optimize besides images are render-blocking scripts.
So you want to find a good balance between loading in the 'skeleton' CSS and content first, and then following everything else to create the illusion that the page has loaded faster. This is called
Meaningful Paint, and it makes up a family of related metrics around 'Web Experience' which you can read about here: https://calibreapp.com/blog/reconsider-tracking-fmp ... the TLDR version is that to optimize how fast a page feels, load in the things that don't affect the visual experience last. Autoptimize, mentioned above, is what can help with that: deferred loading.
Fonts - like images - cause a surprising amount of problems, which is why you should strongly consider what fonts are 'essential' to your experience and remove unnecessary fonts from being loaded.
The biggest mistakes are:
- To load in all of the weights of a font when you might only need regular and italic
- Loading in extra fonts that look nice, but are very rarely used, and
- Loading in full icon fonts when you only need maybe 10 icons max.
To figure out your font situation, do the network-tab audit of your site and sort by
type to see how many fonts you're loading in.
If you're loading in an entire icon font just for a few menu icons, consider replacing those with SVG files (scalable vector graphics -- also optimizable to 5kb per icon) limited to the narrow list you need (and consider embedding the SVG as code rather than as a file request, so that you skip one back-and-forth server trip).
Side note: wordpress doesn't allow SVGs natively so you'll need to change one line of code in core to allow for it. A google search should reveal where you need it.
The other thing about fonts is that not all font sources are created equal. Depending on how comfortable you are with font management, you might also want to load a font in via your own CDN (covered later, below) instead of Google Fonts (which is surprisingly enough not the fastest CDN for fonts). Or you might want to save it in base64 and load it directly in the page html because you can save the server a round trip requesting an additional asset (though having a lot of base64 assets can impact your SEO rankings because crawlers can't tell if it is malicious code or not and ding you for a lack of code readability). If you're using your own CDN, you have control over the fonts and caching. If you're using a font only on one page, loading it as base64 can be worth the effort.
Why mention this? Every little bit counts: optimization, once you've hit the big guns, is all about cutting off 100ms here, 50ms there. They add up.
Side Note: Fonts and Accessibility
Icon-fonts are (since my last research a few years back) problematic for accessibility reasons. This is because icon fonts aren't screen-readable and aren't implemented with the right metadata to guide screen readers.
You MUST consider accessibility in the site design. I can write a whole thing about accessibility, but the core of it is: your site must comply with ADA guidelines on usability and there are a lot of robo-lawsuits out that that programmatically scrape sites and assess them for accessibility issues. Not legal advice, but essentially if you can pass an automated accessibility audit, you're safe from programmatic lawsuits.
That said, you should design for accessibility in mind anyway. Accessibility is ultimately defined as usability by people who are protected by the ADA, which in a court of law is not a technical list of requirements but one based in actual usability. It's not about meeting technical checklists but in actually ensure the site is usable. If you're interested in learning more, there are some tools and best practices for auditing a site for accessibility you should follow.
Getting to 95%: CDNs, Caching, Preloading
This is the remaining 5% to get you to 95%.
CDNs are content delivery networks. You should always aim to cache and deliver your files through CDN to minimize lag time and optimize for geographic location. It might seem silly to bring it up, but there's an actual time difference if you're hosting on a server in NYC to then loading the files to Istanbul. Data travels through wires.
So instead, you use a CDN to syncronize and duplicate your file across a lot of servers worldwide so that you can service Istanbul from Istanbul, New York from New York, and so on. It will cut off some milliseconds off the server load and response times. Cloudflare is generally pretty good for this for self-hosted sites, but if you're using a managed hosting solution they are already doing something like for you (or have options available).
This tends to go hand-in-hand with CDNs, but you want to cache your files. This literally means saving and sending a saved/pre-processed version of your page to others. Caching literally means relying on the server's memory: it's like when someone asks you, "did you lock the front door?" or "what color is your bedroom wall?" – if you just checked 5 minutes ago, then you can rely on your memory... but if it's been a few weeks since you last checked your front door, or you had someone recently repaint your house, you should probably double check again if anything has changed since your last memory.
When a file is cached, the server will send what it's sent before instead of doing a check for the file. You want to do this so that fewer users need to "assemble" the page on their side – it's like the difference between buying a puzzle and buying a poster – if your goal is to get people to admire what you've created faster, ship the the cached filed (the poster).
It will make a big difference, especially if your site doesn't change too often. Cloudflare will do this if your entire site is CDN'd by them. Make sure to give your site a long cache duration (especially if it doesn't change too often), and make sure to clear the cache if you make changes, otherwise they won't be reflected live (because you're serving an old, saved version).
Side note: Caching also happens on the browser level. So your web browser will also save the page and files you loaded previously to render them faster. That why you sometimes need to "clear your cache" in order to see changes or get something to work. In those cases, your browser is using its memory rather than the reality of the site, and that is causing problems because something somewhere changed.
For sites that are dynamic (such as ecomm stores and interactive sites), you can also cache database queries. Wordpress is a good example of a dynamic site - there's a lot of code to "bring parts in from elsewhere". For example, a single page consists of a loop for posts, a loop for tags, a loop for authors and their info... all of which is stored separately and queried and assembled when a page is requested (this is compared to a "static" site where the code is all hard-coded and there is no querying happening on page load).
You can use something like redis cache to save queries, meaning each page has to do less 'computation' to be built. Again, faster load times.
Preloading is an interesting behavioral hack whereby the browser begins to load a page in the background before you even click on the link to go to the next page.
This is great for when you know someone will need certain elements later. For example, you might preload the cart page while the user is on a product page, or start to preload an individual product page's css skeleton while the user is on a product grid.
This can be written into the code manually in the header using the
preload tag, or you can use something like Instant.page to trigger preloads when the user hovers over a link. I recommend checking out Instant.page: the explanation of how it works is pretty clever. Essentially, most people will hover over a link for at least half a second before clicking it, which means you can assume within a quarter-second to start preloading the page ahead of their action.
Bonus 1% Optimization
Most sites today rely on live chat to create a helpful user experience, but not all live chat tools are created equal. Pricing and features are obvious things that people think about when evaluating thier options, but I recommend thinking about site performance as well. Not all live chat plugins are created equal!
I used Drift once and it added an extra 6 fonts, 5mb of code, and 3 seconds of load when implemented. Just awful! The value we gained from flexibility working with consumers was offset by the number of consumers we lost to poor site performance. Same with some other "heavy duty" chat tools – they might be powerful, but that often comes at a performance-level cost.
My personal recommendation is to use Crisp.Chat; they're inexpensive, pretty powerful, and very lightweight.
That covers most of the important stuff about optimization.