WordPress Site Performance

Updated 20-Sep-2023

Site performance comes down to two issues:

  • Perceived relevance
  • Perceived responsiveness

Actually, perceived responsiveness could be considered an aspect of relevance (but not the other way around). To be relevant is to be speedy and relevant.

Catch 22 - Speed vs. Functionality

For WordPress, the architecture is one where responsiveness goes down logarithmically to the amount of functionality and complexity of the system, that is, the more widgets and plugins. That is, the more relevance in terms of function, the less relevance in terms of responsiveness.

This is pretty much by design, as there is no way to try and register globally CSS or Javascript so that it could be managed centrally (via minification and caching). So instead, each plugin or widget makes its calls and shoves its code in a few select spots, in an order that is not fully predetermined.

Minification and Caching

The two strategies for speeding up sites are:

  • Minification (a two part strategy), and
  • Caching (also a two part strategy).

Minification consists essentially in compressing and combining files, with a variety of tools to do so. Compressions means the files are smaller, and combining them means there are fewer, and therefore fewer server requests.

Caching involves both placing files closer to the recipient, as well as keeping them there for future requests. This means both initial requests and subsequent requests are opportunities to prefetch through anticipation. And also to cache various different aspects in various different locations, and with a variety of strategies to expire content so that new content is fetched when needed.

> note: cookies also have a caching mechanism

While minifications are essentially algorithms for compression done just after one or more fragments are constituted, caching is done in a variety of places (browser, forward cache, CDN, web server), and for a variety of things (database, page, object). HTTP headers are one place where caching information is kept.

The Cached and the Uncacheable

In order for these things to work well, there should be a single location where both minification and caching is configured, and a single set of benchmarks that could provide feedback on the best approach for a given site profile. Further, what can and what cannot be cached, and when the can/not caching may or may not be permitted. Various kinds of content might need to be uncachable, at least globally, including:

  • Location-specific content - information for visitors from certain places, such as currency
  • Language-specific content - information in specific languages, which may be identified by browser language
  • Group-specific content - information for people who are a part of a group, such as paying customers, or active leads
  • User-specific content - information for a specific person, such as their transaction history, available when they are logged in
  • Newly updated content - should replace any old content that it replaces in all caches

In most of these examples, there should be some way of changing preferences (location, language, group), when those options are otherwise free choices.

Instantclick / Turbolinks / Progressive Web Apps

Preloading is essentially what caching is, though where the preload happens can vary. By focusing not on the server-side, but the web application side (Instantclick, Turbolinks) and the browser requestor (Progressive Web Apps). By focusing on optimizing the browser render, these tools become much more responsive, such that relevance is increased (to the degree the application, page or site has the proper functionality and content).

Single Page Applications (SPA)

While PWA supports standard websites and is really trying to fix low bandwidth issues, IC and TL essentially turn websites into single page applications, as the entire page loading process is dispensed with, and only changes to pages are introduced. This is a noticeably faster approach. Unfortunately, much of the development, tools, plugins, etc., out there assume the basic model of a clean DOM for every page being called. This means whack-a-mole forever.

WordPress Minification

The big problem with minification on WordPress is that the way plugins interact, the minification process can break things, and ultimately some kinds of content cannot be minified. Thankfully, since plugins are open source on WordPress, it is possible to fork them and fix them (though a costly, time-consuming task). Ultimately, this kind of fixing needs to be accepted upstream, or a huge amount of ongoing maintenance will be needed. Ultimately, porting a number of plugins into custom posts instead is one option. But again, time and resources needed.

CSS Minification

One approach is to strip out all the CSS in every plugin and theme and add it to a single file (or a small set). Maintaining one file is much more manageable.

Javascript Minification

Javascript is a more complex problem because some of it needs to be in certain places in the page. Header, body and footer. Blocking and non-blocking. Essentially Javascript needs to be written for minification and deployed in a theme in such a way as to naturally fit.

Pre-minification of Content

Better is to not minify at page cache, but previous to that, or at least to the degree possible. For a given set of pages on a site, some set or subset of javascripts will be needed. Some will always be present, some will sometimes be present, and there will be a limited number of sets of javascripts. Also, there are certain aspects of the site such as menus which are constructed out of queries, but can also be minified and cached as a set. Contact forms, user account pages, empty shopping carts, and the like can be designed in a way to simply add one more javascript and html component.

Performance Testing Tools