Core Web Vitals · Updated March 2026

How to Fix LCP on Shopify: Get Under 2.5s (Complete 2026 Guide)

Largest Contentful Paint (LCP) measures how long visitors wait before seeing your main content — usually the hero image or product photo. Google wants it under 2.5 seconds. Most Shopify stores score 3–6s on mobile. Here's every fix you need, with real Liquid code and before/after benchmarks.

~16 min read · 3,400 words · Liquid code examples included

What Is LCP and Why It Matters for Shopify Stores

Largest Contentful Paint (LCP) is one of Google's three Core Web Vitals — the metrics that directly influence your search rankings and quantify user experience. While CLS measures visual stability and INP measures interactivity, LCP measures perceived loading speed — specifically, how long it takes for the largest visible element on the page to fully render.

On a Shopify store, the LCP element is almost always an image:

  • Homepage: Hero banner image or the first slide of a slideshow
  • Product pages: The main product image (usually the largest above-the-fold element)
  • Collection pages: Collection banner or the first product card image
  • Blog posts: Featured image

≤ 2.5s

Good

2.5–4.0s

Needs Improvement

> 4.0s

Poor

Why LCP matters for your Shopify store:

  • SEO rankings: Google uses LCP as a ranking signal — pages passing all three Core Web Vitals get a measurable ranking boost
  • Conversions: Deloitte found a 0.1-second improvement in LCP led to an 8% conversion increase for retail sites
  • Bounce rate: Visitors see a blank or partially loaded page while waiting for LCP — each second increases bounce rate by roughly 20%
  • Mobile impact: LCP is typically 2–3× worse on mobile due to slower CPUs and networks — and mobile is what Google measures for ranking

Want a quick check on where you stand? Run a free speed test on your store to see your current LCP score.

The Easy Fix: Automatic LCP Optimization

Before diving into manual theme edits — there's a much faster path. Thunder Page Speed Optimizer automatically tackles the top causes of high LCP on Shopify stores, often reducing LCP by 0.5–2.0 seconds within minutes.

How Thunder fixes LCP:

Smart Script Deferral

Defers render-blocking third-party scripts so the browser reaches and renders your hero image sooner

Critical CSS Inlining

Extracts and inlines above-the-fold CSS so rendering starts without waiting for external stylesheets

Image Loading Priority

Smart lazy loading — never delays the LCP image, uses eager loading + responsive sizing automatically

Font Optimization

Preloads critical fonts and applies font-display: swap to prevent render blocking

Average improvement: +27 PageSpeed points

Typical LCP improvement: 0.5–2.0 seconds. Most stores move from red/orange to green within minutes of enabling Thunder.

Fix Your LCP Score Now →

Free plan available · No credit card required · 30-second setup · Works with all themes

Prefer to do it yourself? Keep reading ↓

How to Measure and Debug Your Shopify Store's LCP

Before fixing LCP, you need to identify your current score, which element is the LCP element, and what's delaying it. Here are the tools that matter:

PageSpeed Insights (Start Here)

Visit pagespeed.web.dev or use our free Shopify speed test tool. Check two sections:

  • Field data (top) — Real user LCP from Chrome users over 28 days. This is what Google uses for rankings.
  • Lab data — Simulated LCP from a controlled test. Useful for immediate before/after testing, but doesn't reflect real-world conditions.

In the Diagnostics section, look for "Largest Contentful Paint element" — it shows exactly which element is your LCP and its load timing breakdown (TTFB, resource load delay, resource load time, element render delay).

Chrome DevTools Performance Tab

Open DevTools (F12), navigate to the Performance tab, enable "Web Vitals" in settings, and record a page reload. The timeline shows a green "LCP" marker at the exact moment the largest element rendered.

  • Hover over the LCP marker to see which DOM element triggered it
  • Look at the Network waterfall to understand why it loaded late — was the image itself slow, or was something blocking it?
  • Check the Main thread flame chart for long tasks (red triangles) that blocked rendering before LCP

Google Search Console (Core Web Vitals Report)

Under Experience → Core Web Vitals, Search Console groups your URLs by LCP status (Good / Needs Improvement / Poor) using real user data. This is the definitive view of how Google sees your LCP. Note: it uses a 28-day rolling average, so improvements take 2–4 weeks to reflect. Use this for tracking progress, not instant feedback.

The LCP Timing Breakdown

Google breaks LCP into four sub-parts. Understanding which phase is slowest tells you exactly what to fix:

TTFB (Time to First Byte)

Server response time. On Shopify: 200–800ms typical.

Resource Load Delay

Time between TTFB and when the LCP image starts loading. Caused by render-blocking scripts.

Resource Load Time

How long the LCP image takes to download. Fix with compression and proper sizing.

Element Render Delay

Gap between image download and actual paint. Caused by CSS or JS blocking render.

The 4 Root Causes of High LCP on Shopify

Every LCP problem traces back to one of these four bottlenecks. Identify yours and jump to the matching fix:

1. Render-Blocking Resources (Most Common)

JavaScript and CSS files that block the browser from rendering anything until they've been downloaded and executed. Even if the hero image downloads quickly, nothing displays until render-blocking scripts finish. On most Shopify stores with 5+ apps, this adds 1–3 seconds to LCP.

Jump to Fix #2

2. Unoptimized LCP Image

The hero image is too large (2+ MB), served in JPEG/PNG instead of WebP, oversized for the display area, or missing responsive srcset. The image file itself takes too long to download, especially on mobile connections where bandwidth is limited.

Jump to Fix #1

3. Lazy-Loaded LCP Element

Many Shopify themes apply loading="lazy" to all images, including the hero. This tells the browser to delay loading the most important image on the page — exactly the opposite of what you want. Shopify's Dawn theme and many others have this pattern.

Jump to Fix #4

4. Slow Server Response (High TTFB)

Time to First Byte over 800ms delays everything downstream. On Shopify, TTFB is mostly controlled by the platform, but complex Liquid templates, excessive metafield lookups, and heavy app code can add 200–500ms to server response time.

Jump to Fix #6

Fix #1: Optimize and Preload the Hero / LCP Image

The single most impactful fix for most Shopify stores: make the LCP image load faster and tell the browser to start loading it immediately. This involves three steps — compress, preload, and prioritize.

Step 1: Compress and Use Responsive Sizing

Your hero image should be under 200KB (ideally under 100KB for mobile). Use Shopify's CDN with the image_url filter to serve properly sized WebP images:

<img 
  src="{{ section.settings.hero_image | image_url: width: 1200 }}"
  srcset="
    {{ section.settings.hero_image | image_url: width: 600 }} 600w,
    {{ section.settings.hero_image | image_url: width: 900 }} 900w,
    {{ section.settings.hero_image | image_url: width: 1200 }} 1200w,
    {{ section.settings.hero_image | image_url: width: 1600 }} 1600w
  "
  sizes="100vw"
  width="1600"
  height="800"
  alt="Your descriptive alt text"
  loading="eager"
  fetchpriority="high"
>

Shopify's CDN automatically converts images to WebP for supported browsers when you use image_url. The srcset attribute ensures mobile devices download a 600px image instead of the full 1600px version — saving hundreds of KB on mobile.

Step 2: Preload the LCP Image

Add a <link rel="preload"> in the <head> of your theme so the browser starts downloading the hero image immediately — before it even reaches the <img> tag in the body:

<!-- Add to <head> in theme.liquid -->
<link 
  rel="preload" 
  as="image"
  imagesrcset="
    {{ section.settings.hero_image | image_url: width: 600 }} 600w,
    {{ section.settings.hero_image | image_url: width: 900 }} 900w,
    {{ section.settings.hero_image | image_url: width: 1200 }} 1200w
  "
  imagesizes="100vw"
  fetchpriority="high"
>

⚠️ Only preload 1–2 resources total. Preloading too many assets is counterproductive — if everything is high priority, nothing is. Preload your hero image and at most one critical font file.

Step 3: Use fetchpriority="high"

The fetchpriority="high" attribute tells the browser this image is more important than other resources competing for bandwidth. Without it, Chrome initially assigns images a "Low" priority and only upgrades above-the-fold images later — by then, precious time is wasted. Adding this hint can shave 100–500ms off LCP.

Important: Always include explicit width and height attributes. These let the browser reserve the correct space before the image loads, preventing Cumulative Layout Shift (CLS) and enabling layout calculations to begin earlier.

Fix #2: Eliminate Render-Blocking JavaScript

On most Shopify stores, render-blocking scripts are the primary cause of high LCP — not the image itself. Here's the sequence that kills your score: browser starts loading the page → encounters render-blocking scripts in the <head> → stops everything to download and execute them → only then discovers and loads the hero image → finally renders it. Those blocking scripts can add 1–3 seconds before the browser even starts working on your LCP element.

⚠️ Difficulty: Advanced. Third-party app scripts are the biggest problem, and you can't edit them directly — they're injected by apps you've installed. Thunder handles this automatically, deferring scripts while preserving dependency chains so apps keep working.

What You Can Do Manually

  • Add defer or async to custom <script> tags you've added to your theme
  • Move inline scripts from <head> to before </body> when they don't need to run early
  • Remove unused apps — each installed app typically adds 1–3 script tags to every page load
  • Audit your theme's theme.liquid for scripts that could be deferred

<!-- ❌ Render-blocking: browser stops to download & execute -->

<script src="custom-feature.js"></script>

<!-- ✅ Deferred: browser downloads in parallel, executes after HTML parse -->

<script src="custom-feature.js" defer></script>

The tricky part: third-party app scripts often have interdependencies. Deferring one script might break another app that depends on it. This is why manual script deferral on Shopify is risky without deep testing. For a complete walkthrough, see our guide to fixing render-blocking resources on Shopify.

Fix #3: Inline Critical CSS for Instant First Paint

CSS is render-blocking by default — the browser won't paint anything until all CSS files in the <head> have downloaded. On a Shopify store with multiple CSS files (theme CSS, app CSS, custom CSS), this can add 500ms–1.5s before any content appears.

The fix: extract the CSS needed for above-the-fold content and inline it directly in a <style> tag in the <head>. Then load the full CSS asynchronously:

<head>
  <!-- Inline critical CSS -->
  <style>
    /* Only styles needed for above-the-fold content */
    .header { ... }
    .hero-section { ... }
    .hero-image { ... }
  </style>

  <!-- Load full CSS asynchronously -->
  <link rel="preload" href="theme.css" as="style" 
        onload="this.onload=null;this.rel='stylesheet'">
  <noscript><link rel="stylesheet" href="theme.css"></noscript>
</head>

Manually identifying and extracting critical CSS is tedious and error-prone — you need to determine exactly which CSS rules apply to the visible viewport at load time, and this differs for every page type (homepage, product, collection). This is one area where automation makes a real difference: Thunder automatically extracts and inlines critical CSS per page type, then loads the rest asynchronously.

Also watch for CSS @import: If your theme or apps use @import inside CSS files, it creates a loading waterfall — the browser downloads CSS, discovers the import, then downloads more CSS. Replace @import with separate <link> tags to allow parallel downloads. Learn more about render-blocking resources and CSS waterfalls.

Fix #4: Stop Lazy-Loading Your LCP Element

This is one of the most common LCP mistakes on Shopify — and one of the easiest to fix. Many themes apply loading="lazy" to every image, including the hero banner. Lazy loading tells the browser to delay loading the image until the user scrolls near it. For your most important above-the-fold image, this is a performance killer.

How to Check

Right-click your hero image → Inspect → look at the <img> tag. If it has loading="lazy", that's hurting your LCP. PageSpeed Insights also flags this specifically: look for "Largest Contentful Paint image was lazily loaded" in the diagnostics.

The Fix

<!-- ❌ WRONG: Lazy-loading the hero image -->

<img src="hero.jpg" loading="lazy" alt="...">

<!-- ✅ CORRECT: Eager loading with high priority -->

<img src="hero.jpg" loading="eager" fetchpriority="high" alt="...">

Shopify Theme-Specific Fix (Dawn and Similar)

In Shopify's Dawn theme (and themes based on it), look for the hero section file — usually sections/image-banner.liquid or sections/slideshow.liquid. Find where the image is rendered and ensure the first above-the-fold image uses loading: 'eager':

{{ section.settings.image | image_url: width: 1200 | image_tag: loading: 'eager', fetchpriority: 'high', sizes: '100vw' }}

Rule of thumb: The first 1–2 images visible on initial page load → loading="eager". Everything below the fold → loading="lazy". For a deep dive, see our Shopify lazy loading guide and lazy vs eager loading comparison.

Fix #5: Optimize Font Loading for Faster LCP

If your LCP element is text (a headline or paragraph), font loading directly impacts LCP. The browser won't paint text until its font is ready — unless you tell it otherwise. Even when the LCP element is an image, slow font loading can still delay rendering by blocking layout calculations.

Font Loading Checklist

  • Add font-display: swap to all @font-face rules — shows text immediately in a fallback font while custom fonts load
  • Preload your body font: <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
  • Self-host fonts instead of loading from Google Fonts — eliminates an extra DNS lookup and connection
  • Limit font weights: Each weight (Regular, Bold, etc.) is a separate file. Stick to 2 weights if possible
  • Use WOFF2 format — 30% smaller than WOFF, supported by all modern browsers
@font-face {
  font-family: 'YourBrandFont';
  src: url('/fonts/brand-regular.woff2') format('woff2');
  font-display: swap;
  font-weight: 400;
}

@font-face {
  font-family: 'YourBrandFont';
  src: url('/fonts/brand-bold.woff2') format('woff2');
  font-display: swap;
  font-weight: 700;
}

Note: font-display: swap can introduce a minor CLS issue when the custom font swaps in with different metrics. If this is a concern, use font-display: optional — it only uses the custom font if it loads within ~100ms, otherwise sticks with the fallback. Zero swap means zero CLS, though the custom font may not display on slow connections.

Fix #6: Reduce Server Response Time (TTFB)

Time to First Byte (TTFB) is the delay between the browser requesting your page and receiving the first byte of HTML. High TTFB delays everything downstream — including LCP — because nothing can render until the HTML starts arriving. On Shopify, TTFB is typically 200–800ms.

You can't change Shopify's server hardware, but you can reduce how much work the server does per request:

  • Simplify Liquid templates: Deeply nested for loops, excessive if/elsif chains, and complex Liquid math increase server-side render time
  • Reduce metafield lookups: Each metafield access is a database query. Minimize metafield usage on high-traffic pages (homepage, collections)
  • Limit collection products per page: Rendering 48 product cards requires more server processing than 24. Use pagination
  • Audit app-injected Liquid: Some apps inject Liquid code that runs server-side on every page load, even pages where the app isn't used. Check your theme files for app-related Liquid snippets
  • Use sections and section groups: Shopify's newer section rendering can cache individual sections, reducing overall render time

How to check TTFB: In Chrome DevTools → Network tab, click on the first HTML request and check "Waiting for server response" in the Timing breakdown. Under 600ms is acceptable for Shopify; over 1 second usually means complex Liquid or too many app scripts running server-side. For a more thorough analysis, try our Shopify performance analyzer.

Fix #7: Remove Image Transitions on the LCP Element

Many Shopify themes add a CSS fade-in or slide-in animation to images as they load. While this looks smooth, it directly hurts LCP because the browser reports LCP only after the animation completes — not when the image first appears. Shopify's own performance team documented a case where removing image transitions on the hero image improved LCP by 6 seconds on one store.

Check your theme's CSS for transitions on the hero image or its container:

/* ❌ This delays LCP reporting */

.hero-image {
  opacity: 0;
  transition: opacity 0.5s ease;
}
.hero-image.loaded {
  opacity: 1;
}

/* ✅ Remove the transition from the LCP image */

.hero-image {
  opacity: 1; /* Visible immediately */
}

If you want to keep fade-in animations on other images for aesthetics, that's fine — just remove them from the hero/LCP element specifically. You can scope this with a class like .hero-image--no-transition on the first image only.

Manual LCP Fixes vs Thunder: Side-by-Side Comparison

Here's how the manual approach compares to letting Thunder handle LCP optimization automatically:

LCP Fix Manual Approach Thunder Approach
Render-blocking scripts Identify each script, add defer/async, test for broken dependencies — risky with 3rd-party apps Automatic dependency-aware script deferral; preserves app functionality
Critical CSS Manually extract above-the-fold CSS per page type, inline it, load rest async Automated critical CSS extraction and inlining per page type
Image optimization Edit Liquid templates: add srcset, eager loading, fetchpriority, preload hints Smart lazy loading (never on LCP), responsive sizing, priority hints
Font optimization Edit @font-face rules, add font-display: swap, preload hints, self-host Automatic font-display optimization and preloading
Typical LCP improvement 0.5–3.0s (depends on skill level and store complexity) 0.5–2.0s (consistent across themes)
Time to implement 4–12 hours (includes testing and debugging broken scripts) 30 seconds (one-click install)
Ongoing maintenance Must redo after theme updates, new app installs, or layout changes Adapts automatically to theme and app changes

Manual fixes give full control but require Liquid/CSS expertise and ongoing maintenance. Thunder handles the heavy lifting automatically and adapts as your store changes. Many merchants combine both: install Thunder for script deferral and critical CSS, then apply manual fixes for store-specific issues like hero image preloading. See Thunder pricing plans or compare with other speed optimization apps.

Frequently Asked Questions About Shopify LCP

What is a good LCP score for a Shopify store?

Google considers LCP under 2.5 seconds as 'good,' 2.5–4.0 seconds as 'needs improvement,' and over 4.0 seconds as 'poor.' Most unoptimized Shopify stores score between 3.0–6.0 seconds on mobile. After optimization, achieving 2.0–3.0 seconds is realistic for most stores. Getting under 2.0 seconds on mobile is excellent but challenging due to Shopify's platform JavaScript overhead and server response times.

What is the LCP element on most Shopify pages?

On homepage: the hero banner image or slideshow first slide. On product pages: the main product image. On collection pages: the collection banner or first product image in the grid. On blog posts: the featured image. You can identify your specific LCP element using PageSpeed Insights — scroll to the diagnostics section and look for 'Largest Contentful Paint element.' Chrome DevTools Performance tab also shows a green LCP marker on the timeline.

Does LCP affect Shopify SEO rankings?

Yes. LCP is one of three Core Web Vitals (alongside INP and CLS) that Google uses as ranking signals. Pages with 'good' Core Web Vitals scores get a ranking boost in search results. While content relevance remains the primary factor, LCP can be the tiebreaker between competing pages. Deloitte found that a 0.1-second improvement in LCP led to an 8% increase in conversions for retail sites, and Google has confirmed CWV is a page experience ranking signal since 2021.

Why is my Shopify LCP worse on mobile than desktop?

Three factors: (1) Mobile devices have slower CPUs — JavaScript parsing and execution takes 2–4× longer, delaying rendering. (2) Mobile networks have higher latency and slower throughput than broadband. (3) Shopify often serves similarly sized images to mobile despite smaller screens. Google's lab testing throttles CPU by 4× and simulates slow 4G to replicate mid-range mobile conditions. Always optimize and test for mobile first since that's what Google uses for ranking.

Can a Shopify speed app actually fix LCP?

Yes, significantly. Thunder Page Speed Optimizer addresses LCP by deferring render-blocking JavaScript, inlining critical CSS above the fold, optimizing image loading priorities, and preloading fonts. This lets the browser discover and render your hero image much sooner. Users see an average +27 PageSpeed point improvement, with typical LCP reductions of 0.5–2.0 seconds. It works with all Shopify themes and takes about 30 seconds to set up.

How long does it take for LCP improvements to show in Google Search Console?

Google Search Console uses Chrome User Experience Report (CrUX) data, which is a rolling 28-day average of real user metrics. After making LCP improvements, expect 2–4 weeks before the data fully updates in Search Console. Lab tools like PageSpeed Insights show improvements immediately — use those for testing. You can also check your CrUX data directly at the Chrome UX Report dashboard for faster feedback than waiting for GSC to update.

What causes high TTFB on Shopify and can I fix it?

Time to First Byte (TTFB) on Shopify is typically 200–800ms and is mostly controlled by Shopify's infrastructure. However, you can reduce it by: simplifying complex Liquid templates with nested loops, reducing metafield lookups on frequently visited pages, lowering products-per-page on collection pages, and removing unused app code from Liquid files. You cannot change the server hardware or CDN configuration since Shopify manages that, but keeping your theme code efficient helps keep TTFB in the acceptable range.

Do It Yourself

Free plan · 1-click install · Instant results

Install Thunder Free →

Done For You

Core Web Vitals guarantee · 2-week delivery · 6 months Thunder free

Get Expert Optimization →

Starting from €1,500