Throughout this series focused on web performance, you and I took a deep dive into the underlying philosophy and technological intricacies that impact performance in an online context.
Sometimes, I purposely took things slow and meandered into the all-to-important human side of things (probably bordering boredom), while, at other times, I picked up speed (for extra drama) when the more technical aspects needed to be analyzed.
Now, we are going to go bananas. 🐒 I believe the time is right for a brain-dump of all the actionable things I have learned and tested throughout the years, in the WordPress ecosystem. So roll up your sleeves, put on a bandana, and try to keep up.
There is no getting around this one. You can not have a performant WordPress site without some form of caching, at least not in this day and age.
The expectations of both users and the Googles of the world have reached such heights that no matter how fast your PHP server is, it can’t serve up the HTML of your pages at the speed required for a blazing fast experience.
WordPress has no shortage of caching plugins that promise to take this off your plate. Sadly, the sheer volume of options doesn’t make your life consistently easier. This is because caching, despite being on everyone’s tongue, is not an easy problem to solve.
Sure, one could boil it down to: just capture the entire HTML of each page, save it as an HTML file somewhere, and then serve that directly, bypassing the PHP server.
The problem is that this is only half the problem, the easy part; the harder part is invalidating or refreshing the cache once you update your content (including publishing a new post, updating a plugin or theme).
Any self-respecting computer engineer will tell you that the two hardest problems in computer science, by far, are “naming things” (I am not kidding) and “cache invalidation.”
When it comes to caching, the last thing you want to do is a full cache refresh – delete everything you have in the cache and let it rebuild itself. This is very resource intensive and can temporarily degrade your website performance.
What you want is to refresh the least amount of cached pages while maintaining consistency. Easier said than done with highly dynamic, interconnected pages (like the sites we have today).
Since you don’t want to get bogged down into all the technical details of your site’s content, you rely on the caching plugin to do the hard work of determining (programmatically) what should be refreshed on each modification you make. Few plugins manage to do this consistently.
My go-to solution for caching today is WP Rocket. This is hands down the most bulletproof caching solution in the WordPress ecosystem today. To top it all up, this is also one of the easiest to use – talk about win-win situations. It is a premium plugin, but I am very confident it is worth every penny.
So do yourself a favor and don’t bother with free solutions. You are just going to waste a ton of time, endure plenty of headaches, only to come back to this solution.
Note: Managed WordPress hosting services usually have very good caching solutions implemented at a lower level (right in their infrastructure, not as WordPress plugins). You would have a hard time getting better performance out of a plugin solution (WP Rocket included). One thing to keep in mind when choosing your hosting.
…except for WooCommerce
The dynamic nature of eCommerce makes it very hard and very tricky to cache. In the case of full-page caching (the most common type), if a single thing on the page changes, the entire page cache needs to be refreshed.
WooCommerce pages like checkout, cart, account are always left uncached (they might be referred to as skipped or excluded). This is because 99% of the time, each visitor to those pages will see different content, so there is no point in even trying to cache them.
Now you may have landing pages, pricing, or product pages that adapt to the user’s journey through your site. Those too can’t be cached because for the same URL you are using different content depending on who is watching.
You will need to manually fine tune the caching settings to account for this since no plugin can be aware of these particularities of your site.
Even if you can’t cache the HTML of these pages, you can still cache optimized versions of the static assets on these pages, like CSS, JS, and image files.
This is more the realm of art, than exact science because there is a truckload of factors that come into play: from your server’s capabilities, to whether or not to use a CDN service, to what plugins you are using, to finally the way your theme displays things. Best to leave this part to professionals, if you can afford it.
Note: There are dedicated managed WordPress hosting services aimed explicitly at WooCommerce that, again, take care of this on a lower level. They are not cheap, but if your sales can take it, you might want to consider them. Cloudways and LiquidWeb are a few of them.
Caching on steroids
All I have said so far applies in situations where you go for off-the-shelf, relatively cheap solutions. The kind of solutions most suited to individuals or small companies. But for the curious bunch among you, let me take a brief stab at explaining the way the “big boys” do it – just for the sake of keeping things in perspective.
As a site owner, you might drool over the speed of the BBCs and Amazons of the world. You might even wonder: is there a way my site could load this fast? Open up your umbrellas: no, it couldn’t – not at a similar complexity.
To get to that level of performance, and keep it up there, you would need a totally custom site tailored to your content needs, your audience, and priorities. You simply cannot expect something off-the-shelf to have this kind of adaptability, even if “it’s just code.”
The “big boys” have tens, most often hundreds of designers and developers working to fine-tune that, optimize this, rebuild that using the latest and greatest technological advancement, rewrite this part for a minor increase in performance (and engagement). Performance at scale is hard and expensive.
Let me just give you a quick peek into such a high-end approach to the problem of cache invalidation described earlier.
First, full cache refresh is not an option – some people will probably get fired if it comes down to that.
Second, there is no single cache. There are layers upon layers of caches, each dedicated to a specific part of the page or of the data needed on that page.
Third, a page is constructed from different components, each with their separate pipeline for generating the final HTML you see.
Forth, each distinctive page (such as the product page) is optimized to contain the bare minimum in terms of CSS and JS (no global theme style.css in sight).
Finally, nobody working on the content-side of such a site has the smallest expectation that his or her changes will appear immediately live (such as a product description change). The changes will be allowed to propagate throughout the various layers as fast as possible without damaging the performance and stability of the system.
As you can see, it’s OK to be curious and dream about performance Nirvana, but you need to be pragmatic about the costs and dedication involved.
Not from your neighborhood
When it comes to web performance, you need to get to grips with the fact that what matters is the experience of your audience, no matter where they might be located.
Often, people test their site on their own computer and phone, both on the same broadband connection. Sometimes, they might ask a friend or two to do the same from their home – most often they live nearby and have about the same income, hence the same high internet speed.
To mitigate this bias, a whole host of online services have sprung up, including the one from the “big daddy” of web performance, Google’s PageSpeed Insights. They analyze things algorithmically, following the latest guidelines and recommendations, from various locations around the world. Problem solved, carry on.
Not so fast. You need to do something with those insights, on top of the knowledge only you can possess. First, based on your target audience, you decide where your hosting should have its servers. The closer to your audience, the better.
Second, you need to gauge the geographical spread of this audience. Is it highly concentrated in a Californian county or a Swiss canton? Or are you targeting English-speaking, bearded males in their 30s – can it get more cliché than this? – from both the US and the European Union?
With the first group, you can get away with just your server, but with the second one, you need to distribute things.
But Vlad, the last I heard we live in the 21st century, the internet is everywhere, I can Facetime with my friends from thousands of miles away, without a hitch.
Yes, it is, and yes you can. But that doesn’t mean anything. The Internet is a very fragile thing, much more so than most of its users realize. The infrastructure it relies on is a hodgepodge of independently developed networks forced to work together to the best of their abilities.
Big companies like Facebook or Netflix have developed a plethora of technologies to mitigate such a reality, but only for specific usages (like video).
CDN to the rescue. The name says it all: Content Delivery Network. Actually, not so much if you are not geekish at heart. A CDN service will spread your site’s static assets (CSS, JS, and image files aka the bulk of the stuff your readers wait for) across a series of interconnected servers.
Nothing unusual if it wasn’t for two characteristics of these servers. One, they are geographically distributed throughout the globe, thus much more likely to be closer to your readers’ location.
Two, they are strategically (and expensively) positioned right next to major Internet junctions (look up “internet backbone” if in search of adventure), thus benefiting from far higher transfer speeds across the globe.
So, sign-up to a CDN provider of your choice (if your hosting provider doesn’t come with one), plug it into your caching solution and let it fly.
CDN on steroids
I’ve already mentioned Cloudflare when I talked about choosing your hosting provider, but only focused on their free plan as a sure way to give your site a performance boost, on the cheap.
Cloudflare is the real deal when it comes to web performance. They have managed to build such a vast, comprehensive and technically advanced stack that one can only marvel at. While their free plan only skims the surface, once you start paying things really take off.
Think of Cloudflare as a way to get access to some of those “big boys toys” that I’ve talked about earlier, but at a fraction of their cost. Hell, most of the large sites out there use them on top of their custom optimizations.
To consider Cloudflare a CDN is a huge understatement. Besides CDN, they provide really advanced security, automatic CSS and JS optimization, automatic image optimization and improved loading, even HTML caching (your visitors could still reach your site even if your server is down), to name a few. Performance and security bonanza.
There are some caveats since this is, after all, a general service with limited flexibility, but you should really give it a try if you are more of a technical kind. Some frictions appear when dealing with highly dynamic pages like the WooCommerce ones, but are solvable with the higher tier plans.
What about those pesky images
Love them all you can, but images are the log in the proverbial eye. No matter what you do to increase your web performance, you always revolve around them since this is the battle that decides the outcome of the war.
Even if you do all the caching in the world, distribute your files at the doorstep of every reader, if left unchecked, your images will still ruin everything.
I’ve already made my peace that you want them, despite my best efforts to explain why you shouldn’t. So what can we do to solve this shit once and for all?
There is no silver bullet since you want them because you intend to show them to your readers. One way or another, the image file needs to get from a server (CDN or not) to your visitor’s browser. That’s a given.
The only way to gain ground is to get creative and take advantage of the limitations inherent in our hardware and minds. Welcome to the land of perceived performance.
We will start by not loading the images at all (don’t show me those bulging eyes), and play a game of chicken with the reader by loading each image as late as possible. Voilà, lazy-loading images!
That is it. The textual content loads as fast as possible, the Googles of the world are happy that people get to actually reading faster, the images are still there for indexing and SEO gains, your readers will not know the difference (most of the time). All these because the actual trickery is mostly done in the browser via a bit of JS.
Lazy-loading images is pretty much mainstream right now. Caching plugins like WP Rocket provide it out-of-the-box (even for videos), services like Cloudflare Pro do it for you (and take it to the extreme – think how images load on Medium).
All you need to do is make sure your WordPress theme plays well with it, as some layout problems might occur, especially with image heavy layouts.
What is going on with plugins
You’ve brought your images into submission, but, somehow you are still not pleasing the metrics Gods. All your effort seems futile. Don’t despair as you have made great strides and what remains is manageable, to some extent.
Most of the remaining “red flags” tools like PageSpeed Insights nag you about are ultimately related to your active WordPress plugins.
The problem is that each plugin with a front-facing job is very likely to add a CSS and/or a JS file to your pages (at least). These allow the plugin to live up to its promise: display a cart button, show a slideshow of images, provide social share buttons or newsletter subscription.
Since each of them is a separate product, each needs to cover for its own needs and behave in a way most likely to cover all use cases, of all users (not just you).
In the ideal scenario, each plugin would add CSS or JS files only to the pages that actually make use of its features. The reality is often somewhere between “I have no reliable way of knowing, so I will load my stuff everywhere” and “I could restrain myself, but I forgot or my developer hasn’t improved me.”
This leaves you, the site owner, with that endless list of files being loaded ruining your previous performance efforts. The solution is neither straight forward, neither without risks.
Note: Besides plugins, analytics, and tracking services (including social buttons) seem to load JS files like it’s Christmas. Exercise extra restraint with those.
One way to clean up your pages from unneeded files are plugins that allow you to decide on a page by page basis (or group of pages) what CSS or JS files should not be loaded since they are not being actually used. One such plugin is Perfmatters.
Armed with such a tool, you start with your most important pages (probably your front page is a good place to start), look at the provided list of files and based on your knowledge decide if it should be there or not.
You can easily break things if you don’t have the full picture, so proceed with care, or leave it up to a professional. Thankfully, there are undo and reset buttons.
The brain-dump is over, and I hope you’ve managed to keep up and get some valuable insights.
Remember that web performance is a never-ending, relentless struggle. Whenever you can find the time or resources to invest in it you should do so since, most often, you need to do stuff just to stay in the same place.
This article is the sixth one in our series about web performance in general, and WordPress in particular. For the sake of navigation, here are the topics covered previously: a holistic view on web performance, decisive steps to choose your site’s hosting service, getting intimate with the journey of an image on the web, setting up your website for top performance, and crafting your website content for performance bliss.