WordPress Performance is a common topic I get asked about and something I help a lot of people with. And with Google focusing more and more on page speed as a ranking signal, it’s something every WordPress developer should be worry about. Below we’ll talk about some of the things that influence WordPress performance (for better and worse), how we quantify it, and what you can do to fix it.
What Influences WordPress Performance?
When thinking of WordPress performance and page speed, it helps to understand a little bit of what’s happening under the hood every time a visitor wants to read one of your pages or blog posts:
- A user finds your page or blog post, either through search results, a link on another site, and e-mail, or whatever.
- The user casks their web browser to load the page of interest.
- The web browser looks up the IP address of your server.
- The web browser sends a request to your server asking for the page of interest.
- Your WordPress server decides how to build the requested page. This involves a number of database queries and lots of PHP code from your theme and plugins and even core WordPress code.
- Eventually the WordPress server returns a giant blob of HTML that describes how to display page.
- The web browser parses that HTML blob and begins to render it.
- The web browser may need to make additional requests to your WordPress server for things like images, JavaScript, videos, CSS, etc.
- Eventually the web browser has all the files it needs to show the final web page.
As you can see, there’s a lot going on just to load a single page. Now multiple this by multiple pages per user (hopefully), and multiple users at the same time. Eventually your WordPress server will become overwhelmed and be unable to keep up. If the number of requests coming in exceeds the rate at which the server can handle them, sites slow down.
How Do You Measure WordPress Performance?
Many performance tools provide some qualitative measure of site speed, something like PageSpeed or YSlow. The problem with these types of measurements is they don’t quantify the user experience. If you get a YSlow score of 80, is that good? The answer is: maybe. It could mean your page loads fast but you you don’t cache anything. This isn’t terrible if your server can keep up with all the additional requests and serve content efficiently.
It could also mean you cache everything, but the time to first byte is unreasonably long and your users are waiting for the page to load. This isn’t as great because users are more likely to drop off your page after a few seconds of waiting. The point is, real users don’t think about their browsing experience in terms of scores between 0 and 100. At the end of the day people only care about how long the page takes to load and be functional.
That’s why I care about 3 things primarily when helping analyze WordPress performance:
- Load Time
- Page Size
- Number of Requests
These are the 3 things we can influence, and thus the areas I focus on. Clearly there is a relationship between them: the load time will go up if there are larger or more files to download from your server. So it’s impossible to isolate any one of these factors and optimize it. Optimizing WordPress sites should look at all 3 factors and what we can do to lower Load Time, which usually means lowering the other two factors.
Improving The WordPress User Experience
So now that we know how WordPress sites can slow down and how to quantify WordPress performance, what can you do to improve the user experience? Below are just a few of things you can do to help speed up your site.
Page Caching
By far one of the biggest performance gains for most sites, page caching is the process of saving the final HTML for a given page, post, etc. to the disk of your web server. As long as that page or post doesn’t change, the web server can safely send back the contents of the cached file instead of executing all the expensive database queries and database code mentioned above. Serving a cached page is limited only to how fast the server’s disk is and how fast the connection between browser and server is. The server CPU and memory, database CPU and memory, number of plugins, etc. are all moot when a cached page is served.
Of course, there are some things to keep in mind. The cached page has to be generated at least once, so inevitably some user will incur the cost of waiting for the page to generate. Some caching plugins are smart enough to prime a cache whenever a page is saved or updated (i.e. they proactively render it and save it to the cache), but for the most part you usually let the cache populate organically as traffic hits your site.
The other thing to keep in mind is that whenever any aspect of your site changes, you need to flush the cache so the latest version of content gets put into the cache. Just about every caching plugin is smart enough to handle page updates because they user standard WordPress hooks to get notified when things get changed. But many caching plugins cannot handle more global events like plugin changes, widget changes, etc. You always have to keep in mind that whenever you make a change that effects every page and post, you should manually flush your cache to make sure visitors see your changes.
And remember, page caching will not make your page render faster necessarily. It simply reduces the time-to-first-byte, which means a web browser can start to render sooner. If the page or post has a ton of JavaScript, CSS, or other external resources then the content still may be delayed while those are downloaded.
One final note: most managed WordPress hosting services include a page cache by default. Avoid using a plugin for page caching if your server already does it for you. It’s likely to be less efficient and may even cause problems with page content.
Content Delivery Network
Content Delivery Networks, or CDNs, are great ways to shed traffic from your site, freeing up your WordPress server to do more meaningful work. CDNs work by saving all of your static files (images, JavaScript, CSS, etc) to their own servers. Whenever a visitor comes to your site, they download the files from the CDN instead of your server.
Why does this matter? Most CDNs have servers around the world. CloudFlare, one of the best free CDNs available, has 102 data centers around the world (22 in North America alone). Each data center will have a copy of your files, and visitors will download them from the nearest city to where they browse from. That means even if your server is in Asia, a visitor in Denver will download files from CloudFlare’s Denver data center, while a visitor in London will download files from the London data center. So not only is your web server spared additional traffic, the user experience is improved due to the decreased latency in the connection.
Just keep in mind that, as with page caching, CDNs come with some considerations. If you modify your images, JavaScript, CSS, etc. you may need to instruct your CDN to purge their cache. This can cause a temporary surge in traffic on your server while the CDN re-populates its cache. Most CDNs expire content periodically based on whatever caching directives you supply, so most of the time you don’t need to worry about your CDN. More on these below.
Combine and Minify JavaScript and CSS
One of the things that drives page load time is having to download multiple files for a single page or post. Even if you’re using page caching and a CDN, if your home page requires 300 images, JavaScript, and CSS files then the user experience will still be subpar. Therefore another technique for improving WordPress performance is to minify and combine static text files.
Minification is the process of stripping unneeded characters from JavaScript and CSS files. Many of these files contain white space and comments that are meant to make the files readable by humans but do not impact their functionality. It turns out that computers don’t need the whitespace and comments like we do, so you can decrease file sizes by stripping them out before sending to the visitor’s web browser. Combining files is just what it sounds like. Think of it like this: if your site has to send back 20 JavaScript files, instead of downloading 20 individual files, your server glues them together and sends back 1 file. This is clearly much more efficient.
Just beware that due to the nature of JavaScript these techniques don’t work on 100% of themes and plugins. I usually enable them one at a time and do a thorough checkout of the site before moving on. And if you’re wondering, these techniques work great with CDNs. Instead of caching 100 files, they just cache a few.
Lossless Image Compression
Many image formats include lots of metadata that doesn’t effect the image quality, but does increase the file size. So another technique for decreasing overall page size is to pass all of your images (and any thumbnails) through a lossless compression engine. These will strip out the metadata from the image files, while leaving the quality unchanged.
There are a number of 3rd party services that can do this but our favorite is Compressor. You can also install plugins that handle this automatically every time a new image file is uploaded. The benefits of using a plugin over the 3rd party site are that they’re more convenient and also handle the different thumbnails your theme may have configured.
Caching Directives
Web browsers usually save images, JavaScript, and CSS from the sites you browse to your local hard drive. This is because there is a good chance that if one page contains a file, another page on the site will need the same file. But knowing how long to keep these cached files can be tricky. Web browsers rely on your server to tell them how long to cache each file before re-requesting it. Note that most CDNs also use these caching rules to determine how long to keep files in their caches.
What About HTTP/2?
You may have heard of HTTP/2 or HTTP 2.0, but what is it? And more importantly, how does it impact WordPress performance? HTTP is the HyperText Transfer Protocol, and version 2 is the latest version of the protocol. HTTP defines the contract the web browsers and web servers, and enables all of the users of the internet to talk in a common language, so to speak. It is completely independent of HTML, so don’t get them confused. HTTP protocol for exchanging information between servers, while HTML is simply a way to describe a document. Each one can exist without the other:
- HTTP can send any file, such as like JPEG, Text, Movies, etc.
- HTML can be sent over FTP, IMAP, SMS, etc.
The point is: even though HTTP and HTML are the cornerstone of the modern web, they are not related and exist totally independent of each other.
What’s so great about HTTP/2? It offers a number of performance improvements over its predecessor, version 1.1. And some of these improvements make the topics discusses above obsolete. The biggest thing is that HTTP/2 offers persistent connections. Normally, a web browser has to re-open a connection for every file it needs to transfer from the web server. This can happen fairly quickly (milliseconds), but multiplied by hundreds of files it can quickly add up. HTTP/2 allows the web browser to open a single connection and leave it open until the web browser has every file it needs to render the page. Because of this, it’s no longer recommended to combine JavaScript and CSS files when using HTTP/2. We only do that to decreases the number of requests, but HTTP/2 makes this a moot issue.
HTTP/2 also alleviates us from having to do what’s known as domain sharding. We purposely did not discuss this above because it’s an advanced topic and requires a custom solution. In practice, it’s only used by sites that serve millions of visitors and not applicable to small business web sites. The idea was that a web browser, using HTTP 1.1, could only have 8 connections open to a single server. To get around this, sites could spread their files across multiple CDN servers with different names. This allowed to a web browser to open up the maximum 8 connections to different servers at the same time, thus speeding up download of files. With persistent connections in HTTP/2, multiple downloads can happen at once. Therefore having to maintain multiple connections to different CDN servers can actually decrease performance.
Another common practice that becomes counter-productive with HTTP/2 is inlining JavaScript and CSS. This involves embedding small bits of JavaScript and CSS into the main HTML file instead of storing them in their own files. Since this added to the number of total requests, it’s been common practice to inline them into the HTML body. The total HTML file size is increased, but it can be downloaded in a single request so was considered a boost. Again, with HTTP/2, all files can be transferred in parallel over a persistent connection so inlining them no longer makes sense.
That’s about it for HTTP/2 performance concerns, though there are plenty of other features that should make you consider switching (assuming your hosting provider supports it). There are no code changes required to your site, nor any special plugins or setup. Remember, HTTP is not HTML. Your WordPress site simply generates HTML, which your hosting provider then transports back to a web browser using HTTP. The choice of HTTP 1.1 vs 2 is typically not one you need to be concerned with, other than wanting to make your site as performant as possible. Not all web hosts offer HTTP/2 support, but it’s slowly becoming more prominent. In fact, the page you’re reading right now was proudly sent to your web browser using HTTP/2.