Performance work has a strict order of operations. Do it out of order and you will spend a week shaving milliseconds off a page that is still shipping a four megabyte hero image.
Work down this list in order. Stop when the numbers are good enough, because there is always another millisecond and it is rarely worth what it costs to find.
1. Images
Almost always the biggest win, and almost always the least interesting work. Serve modern formats, size them correctly, and let the browser pick.
Sizing correctly is the part people skip. WordPress generates several sizes for every upload and emits a srcset, but that only helps if the theme asks for a sensible size in the first place. A card that renders at 400 pixels wide should not be requesting the full size original.
- Register image sizes that match how the design actually uses them
- Serve WebP or AVIF, with a fallback if your audience needs one
- Let everything below the fold lazy load, and explicitly do not lazy load your hero
- Always set width and height so the browser can reserve the space
That last point is a layout stability fix rather than a speed fix, but it lands in the same score and it costs nothing.
2. Fonts
Fonts are the second biggest offender and the one most likely to be invisible in your own testing, because your browser has them cached and your visitors do not.
Self-host them. A third party font service adds a DNS lookup, a connection, and a round trip before a single glyph arrives, and it does it on the critical path. Subset to the characters you use, ship WOFF2, and prefer one variable font over six static weights.
<link
rel="preload"
href="/fonts/inter-variable.woff2"
as="font"
type="font/woff2"
crossorigin
>
Preload only the fonts that appear above the fold, and use font-display: swap so text is readable while they arrive. Preloading everything is the same as preloading nothing.
3. Requests
Every plugin that enqueues a stylesheet on every page is a tax you pay forever. Audit what loads where.
add_action( 'wp_enqueue_scripts', function () {
if ( ! is_page( 'contact' ) ) {
wp_dequeue_style( 'some-plugin-forms' );
wp_dequeue_script( 'some-plugin-forms' );
}
}, 100 );
The priority of 100 matters. Run too early and the handle does not exist yet, so the dequeue silently does nothing and you conclude it did not work.
Before you start dequeuing, count. Open the network panel, sort by size, and look at what is actually large. Most sites have two or three genuine problems and a long tail of things that do not matter.
4. The database
A slow query does not show up as a big file in the network panel. It shows up as a long wait before anything arrives at all, which is the worst kind of slow because the browser has nothing to do in the meantime.
The usual suspects are autoloaded options that have grown to several megabytes, expired transients nobody clears, and meta queries running against unindexed columns on a table with a million rows.
wp db query "SELECT ROUND(SUM(LENGTH(option_value))/1024) AS kb
FROM wp_options WHERE autoload = 'yes';"
Anything over a few hundred kilobytes there is worth investigating. That data is loaded on every single request, including the ones your cache cannot serve.
5. Caching
Page caching turns most of the above into a rounding error for anonymous visitors. It does not fix a slow admin, and it does not fix a slow logged-in experience.
It also does not fix carts, checkouts, or anything else that has to be different for every visitor — which on a store is precisely the part where speed converts into money. That is why caching goes last: it hides the problems on the pages that matter least.
Object caching is the piece more sites should have and fewer do. Redis or Memcached in front of the database helps logged-in traffic and the admin, which page caching cannot touch.
Caching is not a performance strategy. It is what you do after you have one.
Measure on the hardware people have
Testing on a desktop over office broadband tells you almost nothing. Throttle to a mid-tier phone on a slow connection, which is what a meaningful share of your traffic actually is, and test the page people land on rather than the homepage.
Then check the field data. Lab tools tell you what could happen; the Chrome UX Report tells you what did. When the two disagree, believe the field data.

Leave a Reply