Priority hints, an honest look at lazy loading, and why the CDN was not the bottleneck.
The client had already bought a CDN, turned on lazy loading everywhere and compressed every asset. Mobile LCP was still 5.4 seconds. None of those three things was wrong; they were just aimed at the wrong image.
Lazy loading the hero is self-harm
loading="lazy" on the largest element above the fold delays exactly the thing LCP measures.
Half the sites we audit do this, usually because a plugin applied the attribute site-wide. The
fix is one line: the hero image loads eagerly and carries fetchpriority="high", everything
below the fold stays lazy.
The bottleneck was the font
With the image sorted, LCP moved to the headline — which was waiting on a web font that was
waiting on a stylesheet that was waiting on a third-party script. Preconnecting to the font host
and setting display: swap took another 900ms off.
Final number was 2.1 seconds, and the CDN had never been the problem. Measure the actual LCP element before optimising anything; the tooling tells you which one it is.