Google's Core Web Vitals measure three things: how fast the main content appears (LCP), how quickly the page responds to a tap (INP), and how much the layout jumps around while loading (CLS).
Plenty has been written about them. Very little of it says which fixes actually move the number. From the audits we run, it is nearly always the same four.
1. The hero image is the LCP, and it is too big
On most marketing sites the largest contentful paint is the hero image. If it is a 1.4 MB JPEG being displayed at 800 px wide, nothing else you do will rescue the score.
What works:
- resize to the largest size actually displayed, then serve WebP
- set explicit
widthandheightso space is reserved before it loads - never lazy-load the hero — that delays the very thing being measured
- lazy-load everything below the fold
This one change fixes more failing LCP scores than everything else combined.
2. Web fonts block the first paint
A font loaded from a third-party host costs a DNS lookup, a TLS handshake and a round trip before a single character renders.
Self-host the font files, preload the one used above the fold, and set font-display: swap so text is readable immediately in a fallback. Subset to the characters you need — a full Latin-Extended set is often three times the size of what a UK or UAE site uses.
3. Images without dimensions cause the layout to jump
CLS is almost always images and ads. A browser cannot reserve space for an image whose size it does not know, so when it arrives everything below shifts.
Every <img> needs width and height attributes, or an aspect-ratio in CSS. Ad slots need a reserved minimum height. Fonts with very different metrics from their fallback cause a smaller shift too, worth fixing once the big ones are done.
4. Third-party scripts are usually the INP problem
Chat widgets, heat maps, multiple tag managers, a couple of pixels — each one executes on the main thread, and while it does, taps do nothing.
Audit what is actually loading. In most audits we find at least one script nobody remembers adding and nobody is using. Remove those first; defer what remains; load chat widgets on interaction rather than on page load.
How to measure it honestly
Lab tools like Lighthouse are useful for diagnosis but they are a simulation. What Google actually uses is field data — real visits from real devices, in the Chrome UX Report.
So: use Lighthouse to find the cause, but judge the fix by the field data in Search Console, and give it 28 days to reflect the change. A lab score of 100 with failing field data means your real users are on slower devices than your test machine.
What good looks like
For a marketing page, achievable on ordinary hosting with no CDN:
- under 150 KB transferred on the first view
- LCP under 2 seconds on a mid-range phone
- CLS effectively zero
- fewer than 25 requests
That is not an exotic target. It mostly comes from not shipping things you do not need.

