Fix Shopify Page Speed: The Hero Image LCP Trap
If shopify page speed scores stay low after image compression, your hero image is probably loading lazily. Here is the LCP fix in 30 minutes.

Shopify page speed often stays slow after image compression because the hero banner image is loading lazily by default. The fix is one Liquid edit: change the first slideshow or banner image from loading: 'lazy' to loading: 'eager' and add fetchpriority: 'high' so the browser fetches it immediately. If your theme uses the lazysizes JavaScript library, that one-line change is not enough and a second fix is needed.
Across more than 10,000 live Shopify stores measured in March 2026, the average mobile Largest Contentful Paint sat at 12.3 seconds, almost five times Google's 2.5-second threshold for a "good" rating. The single biggest contributor across that dataset was not image weight, app count, or theme choice. It was the hero banner loading lazily by default. Image compression alone almost never moves the score, because the bottleneck is when the download starts, not how big the file is.
Why does shopify page speed stay low after I compress images?
Largest Contentful Paint, or LCP, measures how long it takes the largest visible element on your page to render. On most Shopify homepages, that element is the hero banner image at the top, and the 12.3-second dataset average above is almost entirely driven by that one element on stores running stock themes.
The reason image compression alone often does not move your shopify page speed score is that Shopify themes ship with loading="lazy" set on every image by default. Lazy loading is meant for images below the fold so the browser can defer fetching them. When the same setting is applied to the hero image, the browser waits for the page to partially render and for a JavaScript loader to decide the image is in the viewport before it starts the download. On a slow 4G mobile simulation, that wait can add 4 to 8 seconds to LCP, regardless of how small the image file is.
A merchant on the Horizon theme saw exactly this: their hero image was 99KB and their mobile LCP measured 12.7 seconds with 1,730ms of total blocking time. Compression alone could not fix it because the file size was already small. What held them back was the moment the download started, well after the file size had stopped mattering.
How do I find my LCP element in PageSpeed Insights?
Run your homepage through pagespeed.web.dev on the mobile tab. Under the "Diagnostics" section, look for the line "Largest Contentful Paint element." PageSpeed Insights names the specific HTML element it timed: an <img> tag for the hero, a heading, or a product name. Confirm the LCP is your hero image before you touch any code. On some stores, the LCP is a heading text block, in which case the lazy-loading fix below does not apply.
If the report flags "Largest Contentful Paint image was lazily loaded" under "Opportunities," that is the smoking gun. Click the warning to see which image URL was deferred.
PageSpeed Insights caches results for roughly 5 minutes. Make a change, wait 5 minutes, and re-run the test. Do not refresh the report repeatedly: you will see the same cached result and waste an afternoon believing nothing worked. For a no-cache run with a fixed network profile, WebPageTest.org with "4G Fast" is the most reproducible alternative.
How do I make the hero image load eagerly in my theme?
Create a theme backup before you edit any code. From your Shopify admin, go to Online Store > Themes, find your live theme, click the three-dot menu, and choose Duplicate. The duplicate is your safety net.
Then open Online Store > Themes > Edit Code and find your hero section file. The exact path depends on your theme:
| Theme | Likely file path |
|---|---|
| Dawn | sections/image-banner.liquid or sections/slideshow.liquid |
| Horizon | sections/hero.liquid or sections/slideshow.liquid |
| Premium themes | Search for "hero" or "banner" under sections/ |
In the file, search for the word loading. You will find a line that calls image_tag with loading: 'lazy'. The fix has three steps:
- Wrap the first iteration of the slideshow in a conditional. Most slideshow sections use a
{% for block in section.blocks %}loop. Add{% if forloop.index == 1 %}inside that loop. - For the first iteration, set
loading: 'eager'and addfetchpriority: 'high'. - For all other iterations, keep
loading: 'lazy'andfetchpriority: 'auto'.
The conditional looks something like this: {% if forloop.index == 1 %}{% assign loading = 'eager' %}{% assign fetchpriority = 'high' %}{% else %}{% assign loading = 'lazy' %}{% assign fetchpriority = 'auto' %}{% endif %}. Your existing image_tag call then uses those variables instead of hardcoded strings.
Save the file, wait 5 minutes, and re-run PageSpeed Insights on mobile. A clean fix typically drops LCP by 2 to 5 seconds when no other bottlenecks are involved. If the LCP element on your product pages is the main product image, repeat the same edit in sections/main-product.liquid so the product page LCP gets the same treatment.
What if my theme uses the lazysizes JavaScript library?
Some Shopify themes, mostly older ones and a few third-party premium themes, use a JavaScript library called lazysizes to control image loading. With lazysizes active, setting loading="eager" on the HTML attribute does nothing. The library reads its own data attributes (data-src, data-bg, data-bgset) and overrides the browser's native loading behavior.
To check, go to Edit Code and look in the Assets folder for lazysizes.js or lazysizes.min.js. If you find it, the eager-loading edit above will not move your LCP on its own.
The lazysizes fix is messier. For the hero image element specifically:
- Remove the
lazyloadclass from the element. - Replace
data-srcwith a regularsrcattribute, anddata-srcsetwithsrcset. - If the hero uses a CSS background image controlled by
data-bgordata-bgset, replace those with an inlinebackground-imagestyle using Shopify'simg_urlfilter directly:style="background-image: url({{ section.settings.image | img_url: 'master' }})".
A merchant on the Shopify Community forum tried just removing the lazyload class on its own and the image stopped loading entirely. The full attribute swap is what worked. If you are not comfortable editing Liquid and JavaScript, this is where a help1 expert can take the lazysizes fix from here rather than risk breaking other images on the page.
When does fixing lazy loading not actually fix LCP?
The lazy-loading edit is necessary but not always sufficient. One merchant on the Shopify Community forum had already set both loading="eager" and fetchpriority="high" on the hero image, and still measured a 10,190ms load delay and a 1,650ms render delay. The image was already in WebP and properly sized. The thread sat unsolved.
The reason: render-blocking scripts above the fold can starve the browser's image fetch even when the image is marked high priority. An analysis on one Shopify store attributed an 82% load delay to render-blocking JavaScript taking priority over the LCP image. App scripts that run synchronously in <head>, theme scripts that block rendering, and tracking pixels that fire before the first paint will all push the hero image's actual download window backward.
If your shopify page speed score stays below 60 on mobile after the lazy-loading fix, app scripts are usually the next layer. We covered that path in our guide to fixing shopify page speed when app scripts are blocking the page. Run that one and combine it with this one.
The help1 store scanner checks both at once: it identifies your LCP element, flags loading="lazy" on hero images, and lists the third-party scripts blocking your render path. You see the full picture in 30 seconds rather than running PageSpeed Insights tests in five-minute increments and guessing what changed.
How can I tell if a freelancer actually improved my page speed?
Fiverr and Upwork have a category of "speed optimization" services priced between $30 and $100 that game Lighthouse scores instead of fixing real performance. The trick is to manipulate which element Lighthouse times as the LCP. The freelancer hides the hero image with CSS or replaces it with a smaller decoy that loads quickly. Your Lighthouse score jumps from 35 to 75. The actual page-load experience for a real visitor is unchanged.
To check whether a service genuinely improved your shopify page speed:
- Open Chrome DevTools (Cmd+Option+I on Mac, Ctrl+Shift+I on Windows). Go to the Performance tab. Record a page load with the network throttled to "Fast 3G." Look at which element Chrome identifies as the LCP. If it is a tiny logo, a footer text block, or something off-screen, that is a tell.
- Check Shopify's own Online Store Speed Report under Analytics. This pulls from Chrome User Experience Report (CrUX) field data, not lab tests, so it reflects what real visitors experienced.
- Ask the freelancer to show before-and-after screenshots from PageSpeed Insights' "Diagnostics" panel, not just the score number. The diagnostic should still name your hero image as the LCP element after the fix, with a faster time, not a different element entirely.
CrUX field data uses a 28-day rolling window, so do not expect Shopify's Speed Report to reflect last week's edit immediately. Lighthouse and PageSpeed Insights are the lab tools for the immediate diagnostic; field data is what tells you the change held up with real customers a month later.
Open your homepage in pagespeed.web.dev right now on the mobile tab. If the report shows "Largest Contentful Paint image was lazily loaded" under Opportunities, you have a 30-minute fix in front of you: duplicate your theme, edit your slideshow or banner section, set the first image to eager with high fetchpriority, save, wait 5 minutes, and re-test. If the score barely moves after that, the next layer is your app scripts. And if you would rather have a Shopify expert walk through the code edit live so you do not break a working theme, help1 has experts on standby for that.
Still stuck? Talk to an expert.
Our vetted Shopify experts can fix this issue for you in a live session. $39 per session. Your first 15 minutes are free.