Insights performance
Shopify mobile speed: 7 tactical fixes that actually move LCP
Most Shopify shoppers are on mobile. Most Shopify stores are tuned for desktop. The gap is where conversion leaks live, and the metric that captures it most cleanly is LCP (Largest Contentful Paint) on mobile.
This piece is the practical, ordered fix list. Seven concrete optimizations, ranked by typical impact, that get a median Shopify store from a 3.5-4 second mobile LCP to under 2.5 seconds. Most stores can ship 3-4 of these in an afternoon.
Where you’re starting from
Open PageSpeed Insights and run your homepage on mobile. Note your current LCP. If it’s over 2.5 seconds, you’re failing Google’s threshold. If it’s over 4 seconds, you’re losing a meaningful chunk of mobile sessions to bounce before the page even renders.
The seven fixes below address the most common reasons a Shopify store’s mobile LCP is bad. They’re listed in approximate order of impact for a typical store. Your specific bottleneck may rank differently, which is why running an audit first (Store Auditor does this in 90 seconds) usually beats applying a generic checklist.
Fix 1: Serve your hero image at the right size
The single biggest LCP win on most Shopify stores is correctly sizing the hero image. The default theme code often loads a 1920px wide JPEG and lets the browser scale it down. On a 375px wide phone, that’s 5x more bytes than necessary.
Use Shopify’s image_url filter with an explicit width that matches the device.
{{ section.settings.hero
| image_url: width: 800, format: 'webp'
| image_tag: loading: 'eager', fetchpriority: 'high'
}}
For srcset support across device sizes, use image_tag with widths array. Shopify’s documentation has the full reference.
Expected impact: 500ms to 1.5s of LCP improvement on mobile, depending on how oversized your current hero is.
Fix 2: Preload the hero image
Even with the right size, the browser has to discover the image in the HTML before it can fetch it. Preloading it in the document head moves that discovery to the earliest possible moment.
<link
rel="preload"
as="image"
href="{{ section.settings.hero | image_url: width: 800, format: 'webp' }}"
fetchpriority="high"
/>
Put this in theme.liquid for homepage-specific heroes, or in the section template for product page heroes. Use imagesrcset and imagesizes attributes if you want responsive preload.
Expected impact: 200-400ms LCP improvement.
Fix 3: Move analytics to Shopify Web Pixels
Google Analytics 4, Meta Pixel, and TikTok Pixel installed as inline script tags eat 200-500ms of main-thread time before the hero image can even render. Migrating to Shopify Web Pixels moves them to a sandboxed worker.
There’s a full walkthrough in our piece on Klaviyo and Web Pixels. The same principle applies to GA4, Meta Pixel, and any other tracking script that has a Shopify-native Web Pixels integration.
Expected impact: 300-600ms blocking time removed, which translates to 200-400ms LCP improvement on mobile.
Fix 4: Lazy-load below-the-fold app widgets
Review widgets, recently-viewed carousels, “you might also like” sections. None of these need to render during the initial page load. They’re all below the fold on mobile.
The Intersection Observer pattern in our review widget guide covers the technique. The same pattern works for any below-the-fold app block.
Expected impact: 100-300ms LCP improvement, because the main thread is no longer competing with widget JavaScript for cycles.
Fix 5: Defer chat widgets to user intent
Tidio, Intercom, Gorgias, Drift. Chat widgets routinely ship 150-300KB of JavaScript and execute it eagerly on page load. The shopper who needs chat triggers it themselves. The shopper who doesn’t get a faster page.
The pattern is to remove the inline script tag and replace it with a listener that loads the chat script on first user interaction.
<script>
const events = ['click', 'scroll', 'mouseenter', 'touchstart'];
function loadChat() {
events.forEach(e => window.removeEventListener(e, loadChat));
const s = document.createElement('script');
s.src = 'https://widget-v4.tidiochat.com/...';
s.async = true;
document.head.appendChild(s);
}
events.forEach(e => window.addEventListener(e, loadChat, { once: true, passive: true }));
// Fallback: load after 3s if no interaction
setTimeout(loadChat, 3000);
</script>
Expected impact: 150-300ms blocking time removed, which often resolves INP failures along with the LCP improvement.
Fix 6: Inline critical CSS, defer the rest
Shopify themes typically ship a single CSS bundle that includes styles for every section, even ones that don’t render on the current page. The browser blocks the first paint until that CSS downloads and parses.
The fix is to inline the critical CSS (the styles needed for above-the-fold content) directly in the <head> and defer the rest. Tools like critical (Node.js library) or Shopify’s own inline_style filter help here.
<style>
{{ 'critical.css' | asset_url | asset_content }}
</style>
<link rel="preload" href="{{ 'theme.css' | asset_url }}" as="style" onload="this.rel='stylesheet'">
Expected impact: 100-300ms LCP improvement, especially on slower mobile networks.
Fix 7: Remove apps you’re not actively using
The fastest fix nobody talks about. Open your Shopify admin Apps page and look for apps you haven’t opened in 90 days. Each unused app may still be injecting scripts on your storefront, costing you blocking time for zero business value.
Common candidates we see in audits:
- Old A/B testing tools (Convert, VWO, Optimizely) installed for a single test and never removed.
- Free SEO apps that auto-installed and run analytics on every page load.
- Old “page builder” apps that left scripts behind even after the merchant switched themes.
- Free shipping bar widgets that haven’t been updated in two years.
The Store Auditor audit will name each app with its current blocking time, making the decision to uninstall easy.
Expected impact: highly variable, but this is often the single biggest single fix on stores with 15+ installed apps.
Putting it together
A typical 4 hour optimization session, in order:
- Run an audit. Store Auditor takes 90 seconds.
- Migrate Klaviyo + GA4 + Meta Pixel to Web Pixels. (30 mins)
- Lazy-load review widgets and recently-viewed sections. (45 mins)
- Defer chat widget to user intent. (15 mins)
- Optimize and preload hero image. (20 mins)
- Inline critical CSS, defer rest. (1 hour, requires theme code work)
- Uninstall 2-3 unused apps. (10 mins)
- Re-audit. Verify the gain. (90 seconds)
Most stores doing this work see mobile LCP drop from 3.5-4 seconds to under 2 seconds, which crosses both the Core Web Vitals threshold and the “feels instant” threshold for shoppers.
When to call in help
If your store has more than 20 installed apps, a custom theme, or unusual revenue concentration on a few collection pages, the diagnostic gets harder. That’s where agency-level work matters. Defyn Digital is the Shopify development team that built Store Auditor, and we handle this kind of performance optimization for clients regularly. The audit tool came out of our internal client workflow.