All insights
Engineering· Apr 2, 2026· 16 min read

Shopify performance: from 3.4s LCP to 1.4s in 6 weeks (the engineering playbook)

Most Shopify performance advice is generic. Here's the exact 6-week sequence we've used on 9 stores in the past year — with the specific theme edits, app audits, and CWV thresholds that actually move rankings and revenue.

AM
Aman Mathur
Founder, SERP Axis

1. The economics: why Shopify speed = revenue

Slow Shopify stores leak revenue at every stage. The relationship is empirical, not theoretical:

  • Google rankings: Shopify stores with LCP > 2.5s on mobile rank an average of 3.2 positions lower than peers with LCP < 1.6s (Sistrix, Q1 2026).
  • Conversion rate: every 1s LCP reduction correlates with a 7–12% lift in CR (Deloitte, 'Milliseconds Make Millions', 2024 update).
  • AOV: faster stores have 8–14% higher AOV (Akamai 2024 e-commerce report). Hypothesis: customers browse more product pages when each loads quickly.
  • Bounce rate: a store moving from 4s LCP to 1.5s sees bounce rate drop from ~58% to ~31% (CrUX dataset analysis, 100+ stores).
The math for a $5M GMV store

Going from 3.4s LCP to 1.6s typically lifts CR by ~12% and AOV by ~8%. Compounded: 1.12 × 1.08 = 1.21, or +21% revenue. On $5M GMV, that's $1.05M of new revenue. Six weeks of engineering at $95/hour is ~$30K. ROI: 35×. This is why we lead with this work.

2. Week 1 — audit + baseline

Before any code changes, capture the baseline. Without a baseline, you can't measure impact. Without measurement, the project is religion.

  • PageSpeed Insights for the homepage, top 5 collection pages, top 10 product pages, and the cart. Capture both lab (Lighthouse) and field (CrUX) scores.
  • WebPageTest run from a target geography on a 4G throttled connection. The waterfall view shows what's blocking — that's the engineering target list.
  • Shopify Theme Inspector (the dev tools panel) for Liquid render times.
  • App audit: list every installed app, the JS/CSS each one injects, and on which pages. Many stores have 25–40 apps; about half are on every page.
  • Image audit: total bytes, formats, dimensions, lazy-loaded vs eager.
Quick app inventory script (paste in browser console on storefront)
javascript
// Lists all third-party scripts loaded by the storefront
const scripts = Array.from(document.scripts)
  .filter(s => s.src && !s.src.includes(location.host))
  .map(s => ({
    domain: new URL(s.src).hostname,
    size: 'check Network tab',
    blocking: !s.async && !s.defer,
  }));

console.table(scripts);

// Count scripts by domain
const byDomain = scripts.reduce((acc, s) => {
  acc[s.domain] = (acc[s.domain] || 0) + 1;
  return acc;
}, {});

console.table(byDomain);
// Output: judkoglobal.com: 4, klaviyo.com: 2, hotjar.com: 3, ...
// Each domain is a third-party doing work on the main thread.

3. Week 2 — theme architecture

Shopify Online Store 2.0 themes (Dawn-derived) are dramatically faster than 1.0 themes by default — but they only stay fast if the architecture is preserved. Common architectural mistakes we see:

  • Sections that load on every page even though they're only used on 2 pages. Theme settings let you scope sections; use them.
  • Apps that inject JavaScript into theme.liquid (loads on every page) vs into specific section files (only the relevant pages).
  • Custom theme code that imports the entire theme's JS bundle to add a single feature.
  • Render-blocking external CSS (e.g., Google Fonts loaded before the critical render path).
Section loaded only on relevant pages, with deferred JS
liquid
{% comment %} Custom Featured Reviews section — only on PDP {% endcomment %}
{% if template == 'product' %}
  <section class="custom-reviews" data-product-id="{{ product.id }}">
    <h2>Customer Reviews</h2>
    <div id="reviews-container">
      <div class="skeleton" aria-label="Loading reviews">…</div>
    </div>
  </section>

  {% comment %} Defer the JS until after the main content loads {% endcomment %}
  <script
    src="{{ 'reviews.js' | asset_url }}"
    defer
    data-cfasync="false"
  ></script>
{% endif %}

{% schema %}
{
  "name": "Featured Reviews",
  "tag": "section",
  "presets": [{ "name": "Featured Reviews" }],
  "templates": ["product"]
}
{% endschema %}

4. Week 3 — image strategy

Images are the largest single contributor to LCP on Shopify product pages. Shopify's CDN supports modern formats and responsive sizing — most stores aren't using either correctly.

  • Use the image_url filter with width parameter for responsive srcset. NOT img_url (deprecated in OS 2.0).
  • Specify width and height attributes on every image. Prevents CLS.
  • First product image (LCP candidate): add fetchpriority='high' and loading='eager'. Other product gallery images: loading='lazy'.
  • Lazy-load below-the-fold images. Default in Dawn but easy to break with custom sections.
  • Use AVIF format where supported. Shopify's CDN auto-converts to WebP/AVIF when you use the image_url filter — but only if the source is high-resolution.
Optimal product hero image (LCP target)
liquid
{% liquid
  assign hero = product.featured_image
  assign sizes = '100vw'
%}

<div class="product-hero" style="aspect-ratio: 1 / 1;">
  <img
    srcset="
      {{ hero | image_url: width: 400 }} 400w,
      {{ hero | image_url: width: 800 }} 800w,
      {{ hero | image_url: width: 1200 }} 1200w,
      {{ hero | image_url: width: 1600 }} 1600w
    "
    sizes="{{ sizes }}"
    src="{{ hero | image_url: width: 800 }}"
    alt="{{ hero.alt | escape }}"
    width="{{ hero.width }}"
    height="{{ hero.height }}"
    fetchpriority="high"
    loading="eager"
  />
</div>
Real-world LCP impact

Replacing a 480KB JPEG hero with a srcset-driven AVIF hero (browser picks 280KB version on mobile) typically drops LCP by 1.0–1.6s on 4G. The single most-impactful image change.

5. Week 4 — third-party app surgery

Most Shopify stores have 20–40 apps. Each app injects scripts on the storefront. Each script blocks the main thread or competes for network bandwidth. By week 4 we have full data — now we cut.

  • Audit each app's value vs cost. We've removed apps that injected 200KB of JS to provide a feature the merchant could have done in 12 lines of Liquid.
  • Defer all non-critical apps. Klaviyo's site tracking can be deferred. Hotjar can be deferred. Reviews widgets can be deferred (or rendered server-side via Shopify's built-in product reviews when possible).
  • Replace heavy apps with first-party features where possible. Shopify has built-in reviews, abandoned cart emails, and basic customer accounts — many merchants have apps that duplicate these.
  • Use the 'Web Pixels' API for analytics where supported. Web Pixels run in a sandboxed worker, isolated from the main thread.
App categoryTypical JS weightDefer-able?Replacement option
Reviews (Yotpo, Judge.me)120–280KBYes (lazy on PDP scroll)Shopify product reviews
Email capture (Privy)80–150KBYes (defer until idle)Shopify forms + Klaviyo direct
Analytics (multiple)variesMostlyWeb Pixels API for GA4
Live chat (Tidio, Gorgias)100–250KBYes (load on click)Same — but lazy-load
Upsell / cart drawer50–180KBPartialCustom Liquid + minimal JS

6. Week 5 — Liquid optimization

Liquid is server-side; you can't optimize render time on the client. But you can reduce what Liquid renders to begin with. Three patterns:

  • Pagination on collection pages. Default Dawn paginates at 24. We move to 16 on mobile, 24 on desktop, with infinite scroll deferred until user scrolls. Initial HTML weight drops 30–40%.
  • Lazy-rendered sections. Use the new 'block' API to render sections after first paint. Shopify supports this in OS 2.0 with proper section schemas.
  • Trimmed product JSON. Many themes dump the full product object into the page (variants, all images, all metafields). Trim to only what the customer-facing JS actually needs.
  • Reduce conditional logic. Deeply nested {% if %} chains slow Liquid render. We've seen Liquid render times drop from 320ms to 84ms by simplifying conditionals on heavily-used sections.

7. Week 6 — validation + monitoring

Performance work that isn't monitored regresses. Apps update, new sections get added, marketing installs a new tracking pixel. Without monitoring, you'll be back to 3.4s LCP in a quarter.

  • Set up Vercel Speed Insights or Cloudflare Web Analytics for real-user monitoring. Per-page LCP/INP/CLS, segmented by device.
  • Add Lighthouse CI to your theme deploy pipeline. Block deploys that regress LCP > 0.3s on the homepage or top product page.
  • Monitor third-party JS weight. Each new app install gets reviewed; deploys that add > 50KB of third-party JS without justification get blocked.
  • Quarterly audits. CWV regresses by 6–14% on average per quarter without active maintenance. Schedule a 4-hour audit + fix cycle every quarter.
Real numbers from one client

DTC home goods, ~$5M GMV. Started at 3.4s LCP. After 6 weeks: 1.4s. CR up 14%. AOV up 9%. Q1 revenue: +21%. Six months later, with monitoring + quarterly audits: still at 1.5s. Without monitoring, our regression model predicts they'd have been back to 2.6s by month six.

8. Common Shopify performance traps

  • Installing a 'speed' app. The irony is that most speed apps add 80–150KB of JavaScript to do work the platform already does (lazy-load images, defer scripts). They typically make CWV worse, not better.
  • Optimizing only for Google's ranking — not for users. Lighthouse score 95 with real-user LCP 4.5s is common. The CrUX field data is what matters.
  • Replacing the theme without a migration plan. Yes, faster theme = faster site, but URL structure changes break SEO equity unless redirects are mapped 1:1.
  • Going headless (Hydrogen) for the wrong reasons. Headless solves specific problems (omnichannel content, deep customization). It does NOT inherently make Shopify faster — and operational cost goes up significantly.
  • Ignoring JavaScript bundle from custom apps your team built. We've seen $10K+ of custom-app development sit unused on every page because nobody reviewed it after the original feature shipped.
Tags
ShopifyPerformanceLCPINPCWVE-commerce
4 strategy seats remaining · Q3

The cost of waiting
is your competitor.

Every 90 days you delay is 90 days of authority compounding for someone else. Get the audit. See the math. Then decide.

Money-back
60 days
Reply within
3 hours
Audit value
$2,400 yours, free