Largest contentful paint is the metric closest to what a visitor actually feels: the moment the page is there. We have spent real hours on that first second, and the levers below are the ones that survived contact with production.
The receipts first. On one build, hero LCP went from 13.7 seconds to 2.8 seconds while the page payload dropped from 4.75MB to 1.3MB. On Belzona Baton Rouge, interior pages went from 11.9 seconds of mobile LCP to roughly 3.4. On a manufacturer's site, one focused change moved the homepage from 89 to 96 on mobile.
Let the hero paint immediately
The most expensive habit in modern web animation is the JavaScript-gated reveal: hide everything at opacity zero, wait for the framework to boot, then fade the hero in. It looks slick in a demo. On a throttled phone, we measured a JS-gated hero reveal costing about 2.5 seconds of mobile LCP.
Our hero entrances are CSS keyframes instead. The markup arrives from the server ready to animate, the browser starts the entrance on first paint, and no JavaScript stands between the visitor and the hero.
Fades deserve their own warning. An element that begins at opacity zero never generates an LCP entry, so a fading headline is invisible to the metric no matter how fast it lands. On Kwaan Bear Technology, the hero heading slides into place without a fade, so its very first paint is the one that counts.
Tune image quality per role, not per file
A hero photo sitting behind a dark scrim does not need the same encoding quality as a product photo a buyer will study. We serve AVIF first and tune quality to the image's job: 30 to 40 for photos behind dark overlays, which halves the bytes and looks identical, and 60 to 82 for foreground imagery that has to hold up to inspection.
The LCP image itself gets the full treatment: a priority hint, high fetch priority, and an inlined blur placeholder so the slot is visually occupied while the real pixels arrive. On a healthcare enterprise build, that combination took roughly a second off mobile LCP.
- Explicit size attributes matched to the real CSS breakpoints, so the browser never downloads a larger file than the layout can use.
- Content photos rendered as real image elements, never CSS backgrounds, so the browser's preload scanner can see them coming.
- Every asset hosted first-party, so no third-party DNS lookup ever sits in the critical path.
The over-compression trap
Here is the counterintuitive one. Shrinking a hero image past a certain point makes it blurry without making the page faster, and it can corrupt the measurement on top of that.
Chrome discards images below roughly 0.05 bits per pixel from LCP consideration as low-entropy. On AAS, our hero had been squeezed to about 5KB, and at that size Chrome stopped counting it as the LCP element at all. The measurement quietly shifted to the nav logo, and the score got worse while the page got lighter.
The fix was raising quality from 40 to 60. A slightly heavier hero, a sharper page, and an honest metric. If your reported LCP element is a tiny logo, check whether you compressed your hero out of the running.
No third-party bytes before intent
The fastest request is the one that never happens. Video embeds are the classic offender: one player iframe can drag megabytes of third-party script into a page the visitor may never play. Our video libraries ship as click-to-play facades instead, a poster image and a play button, with the real player loading only on intent. IMS carries an 88-video library this way; a manufacturer's site carries 41. Until someone presses play, the third party does not exist.
Trackers follow the same rule by architecture: nothing analytics-related loads before consent, which means the first paint never has to compete with a tag manager for bandwidth.
Fonts off the critical path
Web fonts are a classic first-second tax. Ours are self-hosted and loaded through the framework's font pipeline, so there is never an external font request. Display strategies are chosen per role: on Polymer Nation, switching the headline font's display strategy took cumulative layout shift from 0.126 to 0 and moved the mobile score from 93 to 98.
Decorative faces get stricter treatment. On one build, a 121KB decorative serif turned out to be the single biggest resource on the critical path, so below-the-fold faces are no longer preloaded at all. We pin exact weights instead of shipping whole variable axes, and on Kwaan Bear Technology we removed blur filters from the hero's glow effects on mobile, where they cost paint time a phone cannot spare.
What survived, summarized
Every lever above is quality-neutral: the design after optimization is pixel for pixel the design before it. That is the standard we hold. Performance work that erases the design is not optimization, it is surrender.
The order matters too. Measure honestly first, fix the render path second, tune assets third. Most slow heroes we inherit are not slow because the image is big. They are slow because JavaScript was allowed to stand in front of the paint.
