The one line that cuts 800ms off most Shopify stores
Your biggest image is queued behind analytics and app scripts. One preload line in the head fixes it, and three rules decide whether it helps or backfires.
Ashraful
Shopify Select Partner

There is one line you can add to a Shopify theme that typically takes 600 to 900 milliseconds off how long your store takes to look loaded.
It is not a trick and it is not new. It is just consistently missing, including from themes that are otherwise well built. We add it on nearly every speed engagement, and it is the single best ratio of result to effort in Shopify performance work.
The problem, without the jargon
When someone opens your product page, the browser reads the HTML top to bottom and starts fetching things as it discovers them.
Your hero image, or your main product image, is usually the biggest visible thing on that first screen. Google measures how long it takes to appear and calls it Largest Contentful Paint. It is one of the three Core Web Vitals, it is a ranking factor, and it correlates with whether people stay.
Here is the catch. On most stores the browser does not discover that image early. It finds it after parsing the stylesheet, because the image is a CSS background. Or after running JavaScript, because a slider sets it. Meanwhile it has already started downloading fonts, analytics, and three app scripts, because those were in the HTML where it could see them.
Your most important image is queued behind things nobody is looking at.
The fix
One line in your theme's <head>:
{%- if section.settings.hero_image -%}
<link rel="preload" as="image"
href="{{ section.settings.hero_image | image_url: width: 1600 }}"
imagesrcset="{{ section.settings.hero_image | image_url: width: 800 }} 800w,
{{ section.settings.hero_image | image_url: width: 1600 }} 1600w,
{{ section.settings.hero_image | image_url: width: 2400 }} 2400w"
imagesizes="100vw"
fetchpriority="high">
{%- endif -%}
That tells the browser, before it has parsed anything else, to start fetching this image now and treat it as important.
imagesrcset and imagesizes matter. Without them you preload one size and the browser may then download a different size for the actual image, so you have made things worse by fetching two files. They must match what your <img> tag asks for.
For a product page, the same thing against the featured image:
{%- if template.name == 'product' and product.featured_image -%}
<link rel="preload" as="image"
href="{{ product.featured_image | image_url: width: 1200 }}"
fetchpriority="high">
{%- endif -%}
Three rules that decide whether it helps
Preload exactly one image per page. Preloading is a priority instruction. Mark five things urgent and you have marked nothing urgent; they compete with each other and with your CSS. One image, the one that is the LCP element.
Only preload what is actually above the fold. If your hero is below a banner on mobile, or the layout differs enough that the LCP element changes between breakpoints, check before assuming. Preloading something the customer has to scroll to is pure waste.
Never combine preload with lazy loading on the same image. This is the most common way to get it wrong, and it produces a slower page than doing nothing:
<!-- wrong: these instructions contradict each other -->
<link rel="preload" as="image" href="hero.jpg">
<img src="hero.jpg" loading="lazy">
One says urgent, the other says wait. Your above-the-fold image should have loading="eager" or no loading attribute at all, plus fetchpriority="high".
Find your actual LCP element first
Do not guess. Chrome tells you.
Open your product page in Chrome, DevTools, Lighthouse, run a mobile audit. In the results, expand the Largest Contentful Paint entry and it names the exact element.
It is not always what you expect. We have found LCP landing on a heading, a review widget, and once on a cookie banner. If your LCP element is a cookie banner, preloading your hero fixes nothing and you have a different problem.
What to expect
On a store where the hero is a CSS background or set by a slider, 600 to 900ms is typical. That is the range we see repeatedly.
On a store where the hero is already a plain <img> high in the HTML, the browser was probably finding it early anyway and the gain is smaller. Still worth doing, but it is not the same win.
If your LCP is over four seconds, preloading alone will not save you. The image is probably enormous, or it is behind a queue of render-blocking scripts. Preloading a 2MB image just fetches 2MB sooner.
The rest of the LCP picture
Preloading helps the browser find the image. These decide how fast it arrives once found.
Serve the right size. Shopify's CDN resizes on request. image_url: width: 1600 gets a 1600px file, not your 4000px original. Get this wrong and you are shipping a desktop-sized image to phones.
Let the CDN pick the format. Shopify serves WebP automatically to browsers that support it, when you use the image filters properly. You do not need an image optimiser app for this.
Reserve the space. Set width and height on the image tag. This does not affect load time but it stops the page jumping as the image arrives, which is the other Core Web Vital, CLS.
Unblock the head. If three scripts are blocking render, the browser cannot paint the image even after downloading it. Preloading and script discipline work together.
Where to put it
In your theme's layout/theme.liquid, inside <head>, before your stylesheet link. It has to be early enough that the browser sees it before anything expensive.
If you use a section-based homepage, you may need to look up the hero from the section settings, which is why the first example above checks section.settings. The exact path depends on your theme.
This is one line of a much longer list. We do Shopify speed work as a fixed-price engagement with a Lighthouse 90+ guarantee and a 14 day re-test, usually shipping inside a week, without rebuilding your theme.
Want to know what your actual LCP element is and what it is costing you? The free store audit runs the real numbers on your product pages and reports back by email. Or book a 30 minute call.
About the author
Ashraful
Shopify Select Partner, Top Rated Plus on Upwork. 700+ Shopify projects shipped over 7+ years: themes, apps, migrations, speed, Hydrogen. Solo shop, no agency middlemen.
Read the full storyWorking on a Shopify project?
That's what I do every day. Pick whichever feels lower-friction.
More from the blog
Keep reading

Your Shopify store has a script budget and you are over it
Nobody decides to make their store slow. It happens one reasonable app at a time. Set the budget, run the audit, and get paid for it in returned subscriptions.
Read
Shopify layout shift: the 3 fixes that move the needle
The page jumps as someone reaches for Add to Cart and they tap the wrong thing. Three causes explain nearly all Shopify CLS, and why your lab score is understating it.
Read
Getting to Lighthouse 90+ on Shopify without a rebuild
Mid-50s to over 90 on mobile without touching the design. The five steps in order, what each is worth, and the three cases where a rebuild genuinely is the answer.
Read