Skip to content
Wideview

Journal / 12 November 2026

WordPress Core Web Vitals: what worked on one site and broke another

George TsokasFounder

A long run of fine bars compressing to the left of a stopwatch dial, with a glowing marker at the shortened end

In April we opened PageSpeed Insights for the site of SeaDreamers, which runs private boat trips in Corfu. On mobile, LCP, the time until the largest element of the page appears, was 22.7 seconds. After our changes it dropped to 2.4. That number also appears on our projects page, and it is measured.

What does not fit in one line is what exactly that 22.7 was measuring, and why the same settings that helped there took LCP on a shop we maintain from 3.7 seconds to 20.4. We are writing down both, because speed on WordPress is rarely about one plugin or one switch.

In short

  • The 22.7 seconds was a lab measurement for the first visitor. Real-user data was already green.
  • The same switches took another shop from 3.7 to 20.4 seconds, so every change is a hypothesis you measure.
  • The biggest gain on the shop was one line inside a plugin, not a cache setting.

What Core Web Vitals measure, and what they do not

Google defines three metrics. According to web.dev, “good” means:

  • LCP (loading) up to 2.5 seconds,
  • INP (response to clicks and taps) up to 200 milliseconds,
  • CLS (how much the page “dances” while loading) up to 0.1.

They are measured at the 75th percentile of visits, separately for mobile and desktop. And something that gets forgotten: the same page says lab measurement does not replace measurement from real users, and that tools like Lighthouse cannot measure INP at all, since there is no person tapping anything.

In the Search documentation, Google writes that Core Web Vitals align with what its ranking systems want to reward. It does not say anywhere that good numbers bring first place. Speed helps, but it does not replace content.

22.7 to 2.4 smobile LCP on one site, lab test
2.4 MBof JavaScript that only checkout needed
160 to 16 KBFont Awesome, down to the 93 icons in use

The 22.7 was a lab measurement

It would be easy to present it as “the site was broken”. It was not. The real-user data (CrUX) was already green on LCP, INP and CLS. The 22.7 was Lighthouse on mobile, with an empty cache and a simulated slow network. That is the first visitor who arrives from an ad or a search, on a phone, having never been there before.

For a business that lives off tourists who see the site once, that visitor is almost everyone. The analysis pointed the same way from several angles: JavaScript and CSS blocking the page from appearing, and a lot of weight before anything showed.

The changes were in LiteSpeed Cache, which is already on our servers:

  • deferring and combining JavaScript,
  • loading CSS asynchronously and combining it,
  • minifying the HTML,
  • removing the WordPress emoji script.

Result: LCP of 2.4 seconds in the same test. If we had stopped here, this article would say “turn on these settings”. That would be bad advice.

The same switches on a shop: LCP from 3.7 to 20.4

On a WooCommerce cosmetics shop we maintain, we tried the same recipe. Combining the CSS produced a file so large that LCP went from 3.7 to 20.4 seconds. We reverted immediately.

Then we tried asynchronous CSS without combining. It was not applied at all, with no message. The reason: LiteSpeed needs “critical CSS” for each variant of the page, and for the variant with webp images it had not been generated. Without it, the feature silently switches itself off. When we pushed it through by hand, time to first paint (FCP) went from 1.1 to 9 seconds, because the critical CSS did not cover enough of the top of the page.

None of it stayed on the site. The lesson for us: every speed setting is a hypothesis that gets measured, one at a time, not a package you switch on.

One more practical point: on the same shop page, mobile Lighthouse gave scores from 33 to 54 across consecutive runs. One measurement tells you nothing. We always run several and also look at real-user data.

Bar chart of mobile LCP in seconds. SeaDreamers: 22.7 before and 2.4 after, against a good threshold of 2.5. Cosmetics shop: 3.7 before and 20.4 after combining CSS, which was reverted.
Mobile LCP in a Lighthouse lab test. The combined-CSS change on the shop was reverted at once.

2.4 MB of JavaScript that only one page needed

What really helped on the shop was not a cache setting. It was a plugin for extra checkout fields, which loaded the WooCommerce Blocks scripts, React included, on every page of the site. About 2.4 MB of JavaScript on the homepage, categories and products, when only checkout needed it.

Our first idea was to remove those scripts with code in the theme. It broke their dependencies, and FCP went from 1.1 to 9 seconds. The fix that stayed was one line inside the plugin itself: load your scripts only if the page is checkout. With a backup of the file, because a plugin update will wipe it and we need to know how to put it back.

Font Awesome: from 160 KB to 16 KB, and a Safari without icons

The same shop loaded the entire Font Awesome CSS, around 160 KB, to show a few dozen icons. We scanned the theme code and 7 live pages (home, shop, product, cart, checkout, account, search) and found 93 icons in use. The new file keeps only those: 16 KB.

It did not go right the first time. Our first script kept only one name for icons that have aliases, so the menu, account and cart icons disappeared. In the fix, a text-replace “cleanup” of the CSS left orphan brackets. Chrome skipped over them. Safari stopped reading the file at that point and showed empty squares where the icons should be. We restored the full file the same day and rebuilt the subset with a script that does not touch the core rules and checks that the brackets close before it writes anything.

Since then, every change to CSS or fonts is checked in Safari too, not just Chrome. An error that only shows on an iPhone will never be seen by someone who works on a computer.

Small things that matter for LCP

  • The main image must not load lazily. The cache plugin was putting lazy-load on the hero image even though the code asked for the opposite. It needed an explicit exception.
  • Preload for the hero image and the main fonts, and fonts from our own server instead of Google Fonts.
  • Dimensions on product images, so the page does not dance (CLS).
  • No fixed aspect ratio on the hero. We tried it for CLS and on mobile the image came out too short. Reverted.

Checklist before you touch speed

  • Look first at real-user data (PageSpeed Insights, top section, or Search Console). If it is green, you know the problem is mostly the first visitor.
  • Run Lighthouse several times, not once.
  • One change at a time, with a measurement before and after and a way back.
  • Find which plugin loads what, on which page. The biggest gain is rarely the cache.
  • Test in Safari and on a real phone, not only on your computer.
  • Keep a backup of every file you edit, especially inside plugins that will be updated.

Our servers run LiteSpeed Enterprise with its built-in cache, as described on Hosting. Speed degrades again with every new plugin, which is why we re-measure it inside the routine of Care. What we built for SeaDreamers and our other clients is on our projects page.

George Tsokas

Founder, Wideview Entertainment. Writes from production, not from theory.

Keep reading