If you’ve searched recently for tips on optimizing WordPress performance, then you have definitely come across various techniques that people recommend. These include all sorts of caching mechanisms, such as reverse proxies, object caching and cache plugins, CSS minification, using sprites for images, and so on. All of them are viable and effective ways to speed up a WordPress website’s performance. However, be careful when implementing any of these techniques, and always test their effect on your particular website.
In this article, we’ll cover some of the most common issues with various speed boosters that I have encountered and share solutions to help you fix those problems or find ways around them.
I will start with the reverse proxies because, when used correctly, they can give you the biggest speed boost and, when used improperly, can cause serious problems, such as making your website inaccessible or showing the wrong information to the wrong visitors.
Reverse proxies, like Varnish and Nginx, stand between your visitors and your Web server. When a request for one of your pages is made, your Web server usually has to execute the PHP service that makes calls to the database and then provides the page output and the static resources needed to visualize the page. With a reverse proxy enabled, this result is cached, and the next time someone requests that page, the ready output will be delivered by the reverse proxy, which is much faster and causes no load on your server.
This is great, but to operate correctly, the cache must be purged every time something on the page has changed. This is where things can go wrong, mostly because WordPress does not natively support reverse proxies and requires additional tweaks for the cache to be cleared correctly. Usually, such tweaks rely on WordPress’ default core hooks (think of them as events) to purge the cache when necessary — when a post is updated, when a comment is added, when a post is created, etc. However, if an important hook is missed in the implementation of the reverse proxy that you’re using, then you might have a problem. Additionally, numerous events — ones not a part of WordPress’ core hooks but rather performed through plugins — could change the content on your website.
When updating, WordPress puts your website in maintenance mode, updates its files and then disables maintenance mode. The reverse proxy could possibly cache some of your pages while your website is in maintenance mode. This means that if the cache is not purged, then this maintenance page would continue being served to visitors, actively preventing them from reaching your website even when it is operational on the Web server.
When you update a plugin, WordPress disables it, deletes its entire folder and then adds the new files. During that time, the plugin does not actually work. If it’s a big plugin that adds a lot of functionality, such as a gallery or online store, then your reverse proxy could cache pages with errors on them, instead of the actual content.
When you update manually, the easy fix is either to disable the cache during the update or to purge the cache manually once you are ready with the update. However, when you use WordPress’ native automatic update, these solutions are not very practical. What a good reverse proxy should do instead is automatically purge the cache on each update event. Because both core and plugin updates have hooks in the core, this is easily achievable and should be done by you (if you are implementing the reverse proxy yourself) or by your hosting provider (if you rely on the host’s implementation).
No matter which WordPress plugin you use for your online store, you should be very, very careful when implementing reverse proxy caching.
For example, you could create a lovely mess with a shopping-cart widget that displays the products that a customer has selected to buy. If that content is cached by the reverse proxies, then all of your visitors would see the products that the first customer has selected for purchase. Things could get even worse if pages containing personal information, such as thank-you pages, are cached and displayed incorrectly to the wrong visitor. Needless to say, this should be avoided at all costs.
The safest way to avoid such problems is to exclude the entire e-commerce part of your website from the cache. Usually, reverse proxies implemented by hosting companies exclude the most common WordPress e-commerce plugins from the cache by default.
If excluding the whole e-commerce part of your website does not sound to you like an elegant solution — because you would obviously lose the speed benefits — then, theoretically, there is a more intricate way around: using Edge Side Includes (ESI) to specify that parts of your pages should not be cached. In theory, you would simply surround your HTML with ESI tags:
Then, the content between those tags would be dynamically retrieved every time this page is requested. Unfortunately, implementing ESI with WordPress is not straightforward at all, due to WordPress’ lack of native support for reverse proxies. Thus, ESI is usually not a viable option with hosts that support reverse proxies. But it is worth considering if you have an online store built with WordPress and you are implementing the reverse proxy yourself.
When you use a rating plugin on a WordPress website that is cached by a reverse proxy, chances are that visitors will often see an incorrect cached rating, instead of the real up-to-date rating. The reason is that a visitor’s vote given through such a plugin is not part of WordPress’ default hooks and will not trigger a cache purge.
Similar to the e-commerce issues, you could either exclude pages that you collect rankings for from the cache or implement the ESI model for those pages, if feasible.
In case your hosting provider doesn’t provide you with a reverse proxy caching service, you could rely on one of the so-called full-page caching plugins for WordPress. When a visitor requests a page, the plugin would save the actual HTML output in a physical file on your server. The next time someone requests that page, it would be served as a static HTML file, which is much slower than a reverse proxy but still faster than not caching at all.
Unfortunately, due to the caching technique being used, all of the possible problems I’ve explained for reverse proxies hold true for the full-page caching plugins, plus some new ones.
Be careful using such caching on a website with many posts or pages. When you create content on a WordPress website, more pages are automatically created than just the one you’re working on directly: category pages that list all posts in that category, tag pages, archives, author pages, pages for uploaded images, etc. All of these add up to a big number of URLs that your website serves. Now, imagine all of those URLs being turned into HTML files in some folder (usually the uploads folder) on your Web server. When thousands of files are in a single directory, even listing those files is difficult, and we’re talking about the Linux OS here. The result for a big website is usually a huge number of files, a heavy I/O load on the server and, eventually, a slower website and problems with the hosting provider.
Object caching is great for a website that gets a lot of requests to its database, and it can really speed up some websites. Memcached stores the result of the most commonly executed queries to your database in the server’s RAM and serves the cached results instead of querying the MySQL server each time. Unfortunately, in some scenarios, you could actually decrease your website’s performance, and here is why.
If you find your website is working more slowly after enabling Memcached, then unfortunately your only solution is either to disable all plugins that store a huge amount of data in the database or to disable the Memcached service itself.
I love sprites for the performance boost they give to a website when used correctly. This is why, when we redesigned SiteGround1 recently, we moved all navigation and UI elements and many other page elements to sprites. Our website became much faster, and we were quite happy with the result. Then, we continued adding elements to the sprite image, until at some point we noticed problems when some pages loaded on iOS devices.
A good man by the name of William Malone has crafted a nifty tool2 to check whether a sprite image will display correctly on all iOS devices. Enter the dimensions of your sprite image in the calculator, and the answer will appear.
If your sprite is too big, a possible solution is to split it into two images. If you have to do this, my advice is to relegate only the newest elements to a new image; otherwise you would have to adjust all of the CSS code that uses the sprite, a task that you’d want to avoid if possible.
Many tools and plugins will automatically minify files. However, some minify more aggressively than simply removing empty symbols. Some tools will rearrange CSS selectors, for example, grouping them by property, etc. In some cases, this could break the entire logic of a CSS file and turn your website into something that merely resembles the original.
Enabling Gzip for WordPress will greatly improve loading speed. Gzip compresses a page’s output and transfers it to the visitor’s browser, like a regular ZIP file, whereupon the browser decompresses and renders it. It’s great because the time a browser takes to decompress archived content is many times less than the time needed to physically transfer the uncompressed content from the server to the browser.
Most WordPress users rely on plugins when they can — at least the ones who can’t or don’t want to code — including for Gzip. Unfortunately, Gzip plugins run through PHP, which, although fast, is not as fast as running directly from the Apache server. All you need to do is install mod_deflate (ask your hosting provider if it is available — it should be because it is pretty much an industry standard) and add a few lines to your .htaccess file:
Knowing all of the risks involved in optimizing the speed of your WordPress website should not stop you from experimenting. To achieve the best results, just follow few simple principles: don’t change too many things at once, benchmark your loading speeds, use staging copies when possible, and test the website’s functionality after applying each new technique. In doing so, you will speed up your website without breaking any functionality or causing problems for visitors.