
To reduce Largest Contentful Paint on a Hyva Magento storefront, identify the LCP element per template, serve the hero as a correctly sized AVIF or WebP image with fetchpriority="high" and a matching preload, stop lazy-loading anything above the fold, and self-host fonts with font-display: swap. Aim for 2.5 seconds at the 75th percentile of field data.
What LCP Actually Measures, and the Target You Are Chasing
Largest Contentful Paint reports the render time of the largest image, text block, or video visible in the viewport, measured from when the user first requested the page. It is one of the three Core Web Vitals, and it is the one most storefronts fail first. Google’s documented LCP thresholds on web.dev are simple: 2.5 seconds or less is good, 2.5 to 4.0 seconds needs improvement, and over 4.0 seconds is poor. The number that matters for ranking and for real users is the 75th percentile of page loads, split by device, taken from field data rather than a single lab run.
That last point trips up a lot of teams. A Lighthouse score of 95 on your laptop tells you almost nothing about the phone on a mid-tier connection that Google is actually scoring. Chrome User Experience Report data, the field data behind the Core Web Vitals assessment, is where your p75 lives. Optimize for that, not for the green number in your local audit.
LCP is not a single event. It breaks into four parts: time to first byte, resource load delay, resource load time, and element render delay. Every fix in this playbook targets one of those four. Knowing which part is your bottleneck is the difference between a real win and a week spent tuning something that was never the problem.
This article is about LCP specifically. It is not about Interaction to Next Paint, which measures responsiveness after the page loads, and it is not about Time to First Byte in isolation, though TTFB caps everything you can achieve here. We cover the interaction between those metrics below, but the levers, the tools, and the wins are LCP-shaped.
First Job: Find the LCP Element on Each Template
You cannot fix an element you have not identified, and the LCP element is different on every template. Open Chrome DevTools, run a Performance trace, and look at the LCP marker in the Timings track. It names the exact node. Do this on a throttled mobile profile, because the LCP element on mobile is frequently not the one you would guess from the desktop layout.
Here is where the LCP element usually lands on a Magento storefront, and what each template needs.
| Template | Typical LCP element | Primary lever | Effort |
|---|---|---|---|
| Homepage | Hero banner image or headline text | Preload + fetchpriority="high" on the hero, or a fast web font for the headline |
Low to medium |
| Product detail (PDP) | Main product image (gallery first slide) | Priority hint on the first gallery image, defer the rest, kill lazy-load on slide one | Medium |
| Category / product list (PLP) | First product tile image, or the category banner | Preload the banner, eager-load only the first row of tiles | Medium |
| CMS / landing | Large background image or hero video poster | Preload the background image referenced in CSS | Low |
| Search results | First result image or the results heading | Same as PLP; often a text LCP that a font fix solves | Low |
Two things fall out of this table. First, a text LCP is a font problem, not an image problem, and the fixes are completely different. Second, the single most common mistake is a hero or first-tile image that has been lazy-loaded by a global rule, which we address next.
The Biggest Levers: Hero Image Handling
For image-based LCP, and that is most homepages, PDPs, and PLPs, the resource load delay and resource load time dominate. Four moves address them.
Stop lazy-loading the LCP image. The web.dev guidance on optimizing LCP is blunt: never lazy-load your LCP image, because it always adds resource load delay. Many Magento themes and image extensions apply loading="lazy" to every image by a blanket rule. On the hero, on the first PDP gallery slide, and on the first row of PLP tiles, that rule is actively hurting you. The browser waits to discover the image is in-viewport before it starts the download, and you have added hundreds of milliseconds for nothing. Set loading="eager" (or omit the attribute) on above-the-fold images and keep loading="lazy" for everything below.
Add fetchpriority="high" to the LCP image. By default the browser assigns images a low priority during the initial page load, then upgrades in-viewport images after layout. The fetchpriority attribute documented on MDN lets you tell the browser up front that this image matters. Put it on the one hero image, the first gallery slide, or the first tile. Do not scatter it across ten images. If everything is high priority, nothing is, and you have just re-created the contention you were trying to fix.
Preload the hero, and match the source exactly. fetchpriority reorders discovered resources; preload makes the resource discoverable earlier. Add <link rel="preload" as="image"> in the head for the hero. If the image uses responsive srcset, add imagesrcset and imagesizes to the preload so the browser preloads the same variant it will actually render, not a different one. A preload that fetches a file the page never uses is pure waste and doubles your bytes. On Hyva, the head is rendered from a PHTML template you control, so injecting a conditional preload for the current page’s hero is straightforward.
Serve AVIF or WebP at the right dimensions. Resource load time is bytes over bandwidth. AVIF typically beats WebP, which beats JPEG, at equal visual quality. Just as important, serve the size you display. Shipping a 2400px hero into a 720px-wide mobile viewport wastes most of the transfer. Use responsive srcset with real breakpoints and correct sizes, and let an image CDN or edge resizer generate the variants. Explicit width and height attributes belong on every one of these images so the browser reserves space and you do not trade an LCP win for a layout shift.
Font Loading When the LCP Element Is Text
When your LCP is a headline or a category title, images are a distraction. The render delay is the browser waiting on a web font.
Set font-display: swap in your @font-face blocks. Without it, the default behavior blocks text rendering for up to three seconds while the font downloads, and that block time lands directly in your LCP. With swap, the browser paints immediately in a fallback face and swaps when the web font arrives. The tradeoff is a flash of unstyled text and a possible layout shift, which you reduce by matching fallback metrics with size-adjust and the ascent-override descriptors.
Self-host your fonts. Pulling a font from Google Fonts or another third-party origin adds a DNS lookup, a TLS handshake, and a connection to a domain the browser has no reason to have opened. Copy the WOFF2 files into your theme, serve them from your own origin, and preload the one or two weights that render above the fold with <link rel="preload" as="font" type="font/woff2" crossorigin>. The crossorigin attribute is mandatory on font preloads even for same-origin fonts, and forgetting it silently double-downloads the file.
Hyva ships on Tailwind, and Hyva 1.3 and later move toward Tailwind v4. The font-family configuration lives in your Tailwind theme config, and the critical point is the same across versions: the fonts you declare as the default sans or display family are the ones that gate your text LCP, so those are the WOFF2 files you self-host and preload. Subset them to the character ranges you actually use to cut the bytes further.
Render-Blocking CSS, JS, and the Hyva Inline Model
Element render delay is often nothing to do with your image or font. It is the browser blocked on CSS or JavaScript in the head before it can paint anything.
This is where Hyva already helps you. A Luma storefront ships a large RequireJS and Knockout stack that blocks and delays first paint. Hyva replaces that with Tailwind’s compiled CSS and inline Alpine.js. Because Hyva inlines the critical CSS and keeps Alpine small and deferred, the render-blocking budget on a stock Hyva page is a fraction of Luma’s. That is a large part of why teams move to Hyva for Core Web Vitals in the first place, and it is worth understanding what your theme is doing before you add anything that undoes it.
The failure mode on Hyva is regression through third-party code. A tag manager loaded synchronously in the head, a chat widget, a reviews script, or a merchandising library can each reintroduce render-blocking work and push out your LCP. Audit what loads before first paint. Move analytics and marketing tags to async or defer, load them after the LCP element, and question any script that insists on running in the head. Alpine’s own initialization is cheap, but a component that does heavy work in x-init on an above-the-fold element can still delay render, so keep above-the-fold Alpine light.
If you are also chasing responsiveness after load, the Alpine patterns that matter there are different from the ones here. We cover them separately in our guide to reducing Magento INP with Hyva and Alpine patterns, and it is worth keeping the two efforts distinct so you do not confuse a render-delay fix with an interaction fix.
TTFB Is the Ceiling on Everything Above
You can preload a perfect AVIF hero and self-host every font, and still fail LCP if the server takes 1.5 seconds to return the HTML. TTFB is a component of LCP, and it is a hard floor: your LCP can never be faster than your TTFB plus the time to load and render the LCP resource. Field TTFB also includes redirect time and connection setup, which is why a chain of redirects or a cold cache quietly wrecks your p75.
On Magento the answer is full page cache served from Varnish, so that repeat and cached page views return HTML in tens of milliseconds instead of running the full PHP and database stack. Make sure your hot templates are actually cacheable and that you are not busting the cache with per-request content in the wrong block. A CDN in front of Varnish moves that cached HTML and your static assets closer to the user, cutting connection setup time for the same bytes.
TTFB is a deep enough topic to stand on its own, and the server, cache, and code fixes go well beyond LCP. We treat it in full in our breakdown of reducing Magento Time to First Byte for Adobe Commerce. For LCP purposes, treat TTFB as the ceiling: fix it first if it is high, because no amount of image work will get you under 2.5 seconds if the HTML arrives at 2.0.
CDN, Edge Image Resizing, and Third-Party Tags
Two infrastructure levers finish the picture. First, edge image resizing. Rather than storing a fixed set of pre-generated sizes, an image CDN generates the exact dimensions and format each device needs on the fly, and caches the result at the edge. That gets you correctly sized AVIF for every breakpoint without a build step, and it shortens both resource load delay and load time because the bytes come from a nearby edge node.
Second, discipline on third-party tags. Every external script is a request to an origin you do not control, competing for bandwidth with your LCP image during the most sensitive window of the load. Load them late, load them async, and drop the ones nobody can name a purpose for. This is the single most common cause of a Hyva store that tested fast at launch and drifted into the yellow six months later as the marketing stack grew.
How LCP, INP, and TTFB Relate
Keep the three metrics distinct so you fix the right thing.
- LCP is a loading metric. It ends when the largest element paints. Everything in this article serves it: images, fonts, render-blocking resources, and the TTFB floor beneath them.
- TTFB is a server-response metric and a sub-part of LCP. It is a necessary input to good LCP but not sufficient; a fast server with a lazy-loaded hero still fails LCP.
- INP is an interaction metric. It measures how quickly the page responds to taps and clicks after it has loaded. A page can have excellent LCP and poor INP, or the reverse. They share almost no fixes.
If you only remember one thing: LCP is about how fast the important thing appears, and TTFB is the part of that you cannot outrun with front-end work.
A Practical Order of Operations
Work the levers in the order they pay off. Check your field TTFB first and fix the cache if it is high. Then identify the real LCP element per template on a throttled mobile trace. Kill lazy-loading on above-the-fold images. Add fetchpriority="high" and a matched preload to the single LCP image. Convert heroes to AVIF or WebP at correct dimensions with explicit width and height. For text LCP, self-host and preload the font with font-display: swap. Finally, audit third-party scripts and move everything non-critical out of the head. Re-measure in the field after each change, because CrUX is where the score you care about lives.
FAQ
What is a good LCP score for a Magento storefront?
2.5 seconds or less at the 75th percentile of field data, measured separately for mobile and desktop. Between 2.5 and 4.0 seconds needs improvement, and above 4.0 seconds is poor. Use Chrome User Experience Report data, not a single lab audit, because Google scores your real users’ devices and connections, not your laptop.
Should I use preload or fetchpriority for the LCP image?
Use both together on the one LCP image. Preload makes the image discoverable earlier in the load; fetchpriority="high" raises its priority among discovered resources. Do not apply high priority to several images at once, and always match a responsive preload to the exact srcset variant the page will render, or you download bytes the page never uses.
Does moving to Hyva automatically fix LCP?
No. Hyva removes most of Luma’s render-blocking JavaScript and inlines critical CSS, which lowers element render delay and gives you a much better starting point. But a lazy-loaded hero, an oversized image, a blocking font, a slow TTFB, or heavy third-party tags will still fail LCP on Hyva. The theme lowers the floor; the per-template work is still yours.
Why is my LCP element a block of text instead of an image?
Because the largest element in the viewport is a headline or title, which is common on category, search, and some CMS pages. Text LCP is a font problem. Set font-display: swap, self-host and preload the above-the-fold font weight with crossorigin, and match fallback metrics so the swap does not cause a layout shift.
Can a lazy-loading plugin hurt LCP?
Yes, and it is one of the most common causes. Extensions that apply loading="lazy" to every image by a blanket rule will lazy-load your hero and first product tiles, adding resource load delay to the exact elements that determine LCP. Exclude above-the-fold images from any global lazy-load rule and reserve lazy-loading for content below the initial viewport.
Where Bemeir Fits
Bemeir is a Brooklyn ecommerce development agency and the USA’s first and leading official Hyva Gold partner, with 16-plus years of Magento and Adobe Commerce work and a Core Web Vitals practice built around the field-data targets above. We build storefronts that measure well where it counts, and we do the unglamorous per-template LCP work that turns a good Lighthouse number into a good CrUX number. See how our ecommerce engineering team works, or read more about Bemeir and the technology partners behind the practice.
Not every storefront is Magento, and the LCP principles carry across platforms. We apply the same image, font, and above-the-fold discipline on Shopify and Shopify Plus builds, on Shopware projects, and on BigCommerce storefronts. We build it, you sell it.





