Core Web Vitals on a WordPress Build
The challenge
A WordPress site with a custom theme failing Core Web Vitals badly enough to be a ranking and conversion liability, with a small fixed budget and a live site that could not be taken down or rebuilt.
- LCP of 7.9 seconds on the primary landing page, well beyond the 2.5s threshold.
- Total Blocking Time of 4,790ms, meaning the page was visually present long before it was usable.
- CLS of 0.162, above the 0.1 threshold, from an unsized image.
- The homepage looked like the same problem but was not, and treating it as one would have burned the budget on the wrong page.
Approach
Fix what is cheap and reversible first. Deferring render-blocking JavaScript, preloading the three above-the-fold font files, setting an explicit aspect ratio on the offending image, and removing jQuery Migrate. Four changes, each isolated in a snippet manager so any one could be reverted independently.
Prove which element is actually the LCP rather than assuming. The homepage
hero image was the obvious suspect. We tested it with a flag-gated experiment: a
query parameter that served an eager <img> hero, run through PageSpeed against
the flagged URL only, so the live site was never altered for real visitors. The
LCP did not move. The hero was exonerated.
Follow the evidence to the real constraint. With the image ruled out, LCP tracked time-to-interactive, which pointed at roughly 156KB of render-blocking main-thread JavaScript from three animation libraries.
Know what is not a snippet fix. Decoupling above-the-fold paint from those libraries meant lazy-initialising the slider, which is development work, not configuration. That went to the client's developers as a written brief rather than being bodged.
What came out of it
- The obvious suspect was eliminated, cheaply. One PageSpeed run against a flag-gated URL was enough to exonerate the hero image, before any budget went into swapping it.
- The real constraint was identified: roughly 156KB of render-blocking main-thread JavaScript from three animation libraries, holding the paint.
- Four reversible fixes shipped inside the four-hour budget, each isolated in a snippet manager so any one could be rolled back independently.
- The fifth issue was correctly scoped as development work, not configuration, and handed over as a written brief the client's developers could implement without further input.
Key insight
The obvious LCP candidate is often wrong, and guessing costs more than testing. A flag-gated live experiment ruled out the hero image in one PageSpeed run and redirected the remaining budget from a cosmetic image swap to the render-blocking JavaScript that was actually holding the paint. It also produced a specific, costed developer brief instead of a vague "improve performance" recommendation.