100% Working Shopify Speed Optimization Case Study (Real Shopify Store Results)

100% Working Shopify Speed Optimization Case Study (Real Shopify Store Results)

This case study walks through a complete Shopify speed optimization project on a mid-size fashion store - from a mobile PageSpeed score of 31 to 79 over three weeks. The store had 18 installed apps, uncompressed product images averaging 1.8MB each, a slider loading 5 hero images on every page visit, and third-party tracking scripts from 9 separate domains. Every fix is documented with before and after metrics, the tools used, and the specific decisions made at each stage.

31 → 79
Mobile PageSpeed score improvement over 18 days of focused optimization work
+65%
Increase in mobile revenue in the 30 days following optimization
-87%
Reduction in homepage page weight from 11.2MB down to 1.4MB
46 hrs
Total developer time across 18 days to complete the full optimization project

The Store: Starting Point and Context

The store is a direct-to-consumer women's clothing brand that had been running for three years on Shopify Plus. The catalog contained approximately 340 active products, most with 3 to 6 color variants and 5 to 8 images per product. Monthly traffic was around 85,000 sessions, with mobile traffic at 71 percent of total sessions.

The mobile conversion gap: Mobile conversion rate was 1.2 percent against a desktop conversion rate of 3.1 percent. The brand attributed this to "mobile users just browsing" - but performance data would later reveal it was largely a speed problem. An 8.4-second LCP on mobile was silently destroying conversions.

The store was running a premium third-party theme purchased two years earlier, which the team had customized heavily for seasonal promotions.

Starting baseline metrics (average of 3 PageSpeed tests):

Page Mobile Score LCP CLS INP Page Weight
Homepage 31 8.4s 0.28 640ms 11.2MB
Product Page 28 6.9s 0.19 520ms 7.8MB
Collection Page 34 5.2s 0.14 410ms 5.9MB

Desktop scores were substantially better: Homepage 71, Product Page 68, Collection Page 74. This is typical - the desktop simulation does not expose the mobile-specific problems that real visitors experience. The team's stated goal was "getting above 50 on mobile." After reviewing the audit results, the revised target became 75+ on mobile with all Core Web Vitals in the Good range.

Phase 1: Full Store Audit

The audit took approximately four hours and used five tools in combination. No fixes were made during this phase - only documentation.

Google PageSpeed Insights

Baseline scores and diagnostic list. Run three times on each page type. Results documented in a spreadsheet.

Chrome DevTools Network Tab

Identified every external domain loading scripts, every image size and format, total page weight, and request count.

Chrome DevTools Coverage Tab

Identified unused JavaScript and CSS percentages by file. Files above 60 percent unused were flagged for conditional loading or removal.

WebPageTest.org Filmstrip View

Showed exactly when content appeared during loading. The homepage took 3.8 seconds to show anything visible and 12 seconds to fully stabilize.

Shopify Theme Inspector

Showed Liquid rendering time by section. The homepage navigation section was rendering in 340ms - far above the acceptable 50ms threshold.

What the audit found - 18 installed apps:

App Script Size Pages Loaded Monthly Cost Last Used
Review app (Yotpo) 142KB All pages $19 Daily
Loyalty program 88KB All pages $49 Weekly
Upsell app 74KB All pages $29 Product only
Size guide 62KB All pages $9 Product only
Countdown timer 38KB All pages $7 Homepage only
Email popup 55KB All pages $15 Homepage only
Currency converter 44KB All pages $0 All pages
Social proof ticker 47KB All pages $19 Unknown
Wishlist app 71KB All pages $9 Product + collection
Back-in-stock app 39KB All pages $19 Product only
Instagram feed 95KB All pages $9 Homepage only
Chat widget 68KB All pages $10 All pages
Subscription app 83KB All pages $39 Product only
Page builder 124KB All pages $39 Landing pages
A/B testing tool 77KB All pages $29 Unknown
Cross-sell app 58KB All pages $19 Cart only
Gift card app 31KB All pages $0 Checkout
SEO booster 29KB All pages $9 Unknown
Total app JavaScript: 1,234KB loading on every page. Total monthly app spend: $329. Every single app was loading its full script bundle on every page - including apps that only functioned on one specific page type. This was the primary cause of the 2,840ms Total Blocking Time.

Additional audit findings: average product image size 1.8MB (JPEG, original camera resolution), hero slider loading 5 images at 2.4MB each (12MB total on every homepage visit), 9 external domains loading scripts, and GA4 firing twice on every page (loaded both directly in theme.liquid and inside the GTM container).

Phase 2: Prioritized Fix Plan

Based on the audit, fixes were ranked by estimated score impact across three weeks of implementation organized into four phases.

1
Image Optimization - Estimated +15 to 20 points. Highest impact, lowest risk, no stakeholder dependencies.
2
App Audit and Script Restriction - Estimated +10 to 15 points. Requires stakeholder alignment before any removals.
3
Liquid Template Cleanup - Estimated +4 to 8 points. Requires Theme Inspector to identify the highest-impact patterns.
4
Advanced Prioritization - Estimated +5 to 10 points. LCP preload, critical CSS, resource hints. Applied last to amplify the gains from earlier phases.

Step 1: Image Optimization (Days 3 to 5)

All product images were replaced using a batch conversion script with Sharp (Node.js) to convert to WebP at 78 percent quality and resize to 1200px maximum width.

const sharp = require('sharp');

async function optimizeImage(inputPath, outputPath) {
  await sharp(inputPath)
    .resize(1200, null, { withoutEnlargement: true, fit: 'inside' })
    .webp({ quality: 78 })
    .toFile(outputPath);
}
The slider replacement decision: The hero slider was replaced with a single hero image. Conversion data showed only the first slide received any clicks - slides 2 through 5 had effectively zero interaction. Removing the slider improved both performance and conversion simultaneously, eliminating 12MB of hero images and the Swiper.js library in one change.
<img
  src="{{ section.settings.hero_image | image_url: width: 1400, format: 'webp' }}"
  srcset="
    {{ section.settings.hero_image | image_url: width: 750, format: 'webp' }} 750w,
    {{ section.settings.hero_image | image_url: width: 1400, format: 'webp' }} 1400w
  "
  sizes="(max-width: 768px) 100vw, 100vw"
  fetchpriority="high"
  loading="eager"
  width="1400"
  height="600"
  alt="{{ section.settings.hero_image.alt | escape }}"
>

Collection page pagination was reduced from 48 products to 24. Lazy loading was added to all product images after the first row.

Results after Step 1 (Day 5):

Page Before After Change
Homepage mobile score 31 49 +18 points
Homepage LCP 8.4s 4.1s -4.3s
Homepage page weight 11.2MB 1.8MB -9.4MB
Product Page mobile score 28 43 +15 points
Collection Page mobile score 34 52 +18 points

Step 2: App Audit and Script Restriction (Days 8 to 13)

Shopify app audit results infographic showing 18 apps organized into four color-coded groups: Removed group in red with 7 apps including A/B testing tool saving 77KB, social proof ticker saving 47KB, SEO booster saving 29KB, page builder saving 124KB, gift card app saving 31KB, back-in-stock app saving 39KB, and cross-sell app saving 58KB with total savings of 405KB and 87 dollars per month; Page-restricted group in orange with 6 apps including size guide, subscription app, wishlist, upsell, Instagram feed, and countdown timer; Deferred group in yellow with 3 apps including chat widget, heatmap tool, and Klaviyo; Kept global group in green with 2 apps including review app and loyalty program
Shopify App Audit Results - 18 apps categorized into four groups based on revenue impact, page specificity, and script weight. The decision framework: Is it generating measurable revenue? Can it be page-restricted? Is there a lighter alternative?

Three questions were applied to each app: Is it generating measurable revenue? Can it be page-restricted rather than global? Is there a lighter alternative?

Removed entirely (7 apps, saving 405KB and $87/month):

A/B testing tool - No active experiments in 4 months. Saved 77KB, $29/month.
Social proof ticker - No click-through data confirming revenue impact. Saved 47KB, $19/month.
SEO booster - Functionality overlapped with Shopify's native SEO features. Saved 29KB, $9/month.
Page builder - Only used for 2 landing pages rebuilt in native Shopify sections. Saved 124KB, $39/month.
Gift card app - Shopify's native gift card feature covered the requirement. Saved 31KB.
Back-in-stock app - Switched to Shopify's native notification. Saved 39KB, $19/month.
Cross-sell app - Shopify's native recommendations API used instead. Saved 58KB, $19/month.

Page-restricted using Liquid conditionals (6 apps):

{% if template == 'product' %}
  {% render 'size-guide-init' %}
  {% render 'subscription-app-init' %}
  {% render 'wishlist-init' %}
{% endif %}

{% if template == 'cart' %}
  {% render 'upsell-init' %}
{% endif %}

{% if template == 'index' %}
  {% render 'instagram-init' %}
  {% render 'countdown-init' %}
  {% render 'popup-init' %}
{% endif %}

Deferred until first interaction (3 apps): Chat widget, heatmap tool, and Klaviyo delayed until first scroll interaction or 4 seconds after load, whichever came first.

var deferredLoaded = false;

function loadDeferredApps() {
  if (deferredLoaded) return;
  deferredLoaded = true;
  // Load chat widget and heatmap here
}

['scroll', 'mousemove', 'touchstart'].forEach(function(e) {
  document.addEventListener(e, loadDeferredApps, { once: true, passive: true });
});

setTimeout(loadDeferredApps, 4000);

Tracking consolidation: GA4 was loading both directly and through GTM - the direct snippet was removed. All tracking (GA4, Facebook Pixel, TikTok Pixel, Pinterest Tag) now runs through GTM. External tracking domains reduced from 9 to 3.

Results after Step 2 (Day 13):

Metric Before After Change
Homepage mobile score 49 61 +12 points
Homepage TBT 2,840ms 980ms -1,860ms
Homepage external domains 9 3 -6 domains
Homepage JS weight 1,234KB 387KB -847KB
Product Page mobile score 43 57 +14 points
Collection Page mobile score 52 64 +12 points
The TBT reduction from 2,840ms to 980ms was the single most impactful change in the entire project. Total Blocking Time carries 30 percent of the PageSpeed score weight - reducing it by 1,860ms in one phase moved the homepage score by 12 points alone.

Step 3: Liquid Template Cleanup (Days 14 to 15)

The mega menu was building by looping all 40+ collections and making metafield lookups on each iteration - 340ms render time on every page of the store.

<!-- Before: inefficient collection loop with metafield lookups -->
{% for collection in collections %}
  {% assign nav_image = collection.metafields.custom.nav_image %}
  {% if nav_image != blank %}
    <a href="{{ collection.url }}">
      <img src="{{ nav_image | image_url: width: 200 }}" alt="{{ collection.title }}">
    </a>
  {% endif %}
{% endfor %}

<!-- After: using linklist, no full collection iteration -->
{% for link in linklists['main-menu'].links %}
  {% if link.type == 'collection_link' %}
    <a href="{{ link.url }}">{{ link.title }}</a>
  {% endif %}
{% endfor %}

Navigation render time after: 28ms (down from 340ms). Six featured collection sections were each making independent collection queries - refactored to use shared section settings, eliminating 5 redundant queries per page load.

Results after Step 3 (Day 15):

Metric Before After Change
Homepage TTFB 680ms 210ms -470ms
Product Page TTFB 590ms 180ms -410ms
Homepage mobile score 61 69 +8 points
Product Page mobile score 57 65 +8 points
The TTFB reduction from 680ms to 210ms came almost entirely from fixing one Liquid pattern rendered on every page of the store. The navigation loop was adding 340ms to every single page load across 85,000 monthly sessions. Fixing one Liquid pattern affected more cumulative load time than most frontend optimizations combined.

Step 4: Advanced Resource Prioritization (Days 16 to 18)

Critical CSS extracted and inlined (14KB inlined, 128KB full stylesheet async):

<head>
  <style>/* 14KB of above-fold critical CSS */</style>
  <link rel="preload" href="{{ 'theme.css' | asset_url }}" as="style"
    onload="this.onload=null;this.rel='stylesheet'">
  <noscript><link rel="stylesheet" href="{{ 'theme.css' | asset_url }}"></noscript>
</head>

LCP image preload with srcset-aware hint:

<link
  rel="preload"
  as="image"
  href="{{ section.settings.hero_image | image_url: width: 1400, format: 'webp' }}"
  imagesrcset="
    {{ section.settings.hero_image | image_url: width: 750, format: 'webp' }} 750w,
    {{ section.settings.hero_image | image_url: width: 1400, format: 'webp' }} 1400w
  "
  imagesizes="100vw"
>

Additional optimizations applied: Preconnects to Shopify CDN and Google Fonts, font weights reduced from 10 to 4 (2 weights each for Playfair Display and Lato), font-display: swap added with preload, and { passive: true } added to 14 scroll and touch event listeners in theme.js.

Results after Step 4 (Day 18):

Page Before After Change
Homepage mobile score 69 79 +10 points
Homepage LCP 3.1s 1.8s -1.3s
Homepage FCP 2.8s 1.2s -1.6s
Homepage CLS 0.28 0.04 -0.24
Product Page mobile score 65 74 +9 points
Collection Page mobile score 68 76 +8 points

Full Before vs After Comparison

Shopify speed optimization before and after comparison infographic split into two columns with a vertical dividing line, left column labeled BEFORE in red showing a score gauge at 31 in red with Homepage LCP 8.4 seconds in red, Page Weight 11.2MB in red, and TBT 2840ms in red, right column labeled AFTER in green showing a score gauge at 79 in green with Homepage LCP 1.8 seconds in green, Page Weight 1.4MB in green, and TBT 312ms in green
Shopify Speed Optimization Before and After - mobile PageSpeed score from 31 to 79, page weight reduced by 87 percent, and all three Core Web Vitals moved from Poor to Good in 18 days of focused optimization work.

Mobile PageSpeed scores:

Page Before After Improvement
Homepage 31 79 +48 points
Product Page 28 74 +46 points
Collection Page 34 76 +42 points

Core Web Vitals:

Metric Before After Status
LCP 8.4s (Poor) 1.8s (Good) Resolved
CLS 0.28 (Poor) 0.04 (Good) Resolved
INP 640ms (Poor) 148ms (Good) Resolved
TTFB 680ms 210ms Significantly improved

Technical metrics:

Metric Before After Change
Homepage page weight 11.2MB 1.4MB -87%
Homepage JS weight 1,234KB 312KB -75%
Homepage image weight 9.8MB 820KB -92%
Homepage request count 142 54 -62%
External domains 9 3 -67%
Installed apps 18 11 -7 apps
Monthly app spend $329 $242 -$87/month

Business metrics (30 days post-optimization vs 30 days prior):

Metric Before After Change
Mobile conversion rate 1.2% 1.9% +58%
Mobile bounce rate 68% 52% -16 points
Mobile sessions per user 1.4 1.8 +29%
Revenue from mobile $41,200 $68,100 +65%
The mobile conversion rate improvement from 1.2 percent to 1.9 percent on 85,000 monthly sessions represented approximately $26,900 additional monthly revenue. The annual revenue impact exceeded $320,000. Total developer time: 46 hours across 18 days.

Challenges Faced

The Page Builder Lock-In

Two landing pages built entirely in the page builder required 6 hours to rebuild in native Shopify sections before the app could be removed. Lesson: page builders create vendor lock-in. Future landing pages were built in native sections from the start.

The Stakeholder Communication Failure

The marketing team had not been informed before the A/B testing app was removed. They discovered it when trying to run a new experiment, creating a same-day reinstall that undid the 77KB savings for two weeks. Lesson: communicate all app changes to stakeholders before implementing, not after.

Critical CSS Drift

Two weeks after implementation, a new homepage section was added without updating the inlined critical CSS. The section rendered without styles for 2 seconds before the full stylesheet loaded. Fix: critical CSS extraction was added as a required step in the deployment checklist for any new above-fold section.

Klaviyo Deferral Broke a Hero Form

Delaying Klaviyo until first scroll broke an email capture form in the hero section. Visitors who submitted before scrolling received no confirmation and were not added to the list. Fix: the hero form was moved to load Klaviyo on page load while all other Klaviyo functionality remained deferred. Lesson: test every form and interaction that depends on third-party scripts after deferral implementation.

Lessons Learned

The Audit Is Worth More Than the Fixes

Knowing exactly what caused the problems before touching anything saved significant time. The impulse to install a speed optimization app at the start would have made things worse - the audit revealed that app scripts were the primary problem.

Mobile Conversion Rate Is the Right Success Metric

Framing around conversion rate changed prioritization. The slider removal became a clear priority because it improved both performance and conversion simultaneously. PageSpeed score is a proxy - conversion rate is the outcome.

App Stack Decisions Are Business Decisions

Removing apps required conversations across marketing, paid social, and customer success. Technical decisions with business implications need stakeholder input. The A/B testing incident happened specifically because this principle was violated.

Liquid Problems Compound Across Every Page Load

The navigation loop was adding 340ms to every page on the store. Fixing one Liquid pattern affected 85,000 monthly sessions - the cumulative impact exceeded most frontend optimizations combined.

Replication Strategy

Shopify speed optimization 3-week project timeline roadmap organized as a horizontal Gantt-style chart with four phases: Week 1 Foundation in blue showing Days 1 to 2 Full Audit, Days 3 to 5 Image Optimization, Days 6 to 7 Lazy Loading and Dimensions; Week 2 Scripts and Apps in orange showing Day 8 Stakeholder Meeting, Days 9 to 10 App Removals, Days 11 to 12 Page Restrictions, Day 13 GTM Consolidation; Week 3 Advanced Optimization in purple showing Day 14 Liquid Cleanup, Day 15 Font Optimization, Day 16 LCP Preload, Day 17 Critical CSS, Day 18 Passive Listeners; Week 4 Verification in green showing PageSpeed Tests, Real Device Testing, and Search Console Review, with score milestones shown as callouts at 31, 49, 61, 69, and 79
Shopify Speed Optimization 3-Week Project Timeline - the sequence matters as much as the fixes. Each phase unlocks more impact from the next. Do not start Week 3 techniques on a store that has not completed Week 1 and Week 2.

For stores with a similar profile (mid-size catalog, 3+ years of app accumulation, premium theme, multiple tracking pixels), this sequence applies directly.

Week 1: Foundation

  • Days 1 to 2: Complete the full audit. Document every app, script size, page weight, and external domain. Do not fix anything until the audit is complete.
  • Days 3 to 5: Image conversion to WebP, resize to display width, implement lazy loading with correct dimensions. Start with hero and homepage images.
  • Days 6 to 7: Apply explicit width and height to every img tag. Implement lazy loading across collection pages.

Week 2: Scripts and Apps

  • Day 8: App audit meeting with all stakeholders. Agree on removals and restrictions before making changes.
  • Days 9 to 10: Remove approved apps. Test PageSpeed after each removal individually.
  • Days 11 to 12: Implement page-specific Liquid conditionals for remaining apps. Test all restricted app functionality on their target pages.
  • Day 13: GTM consolidation. Remove duplicate tracking implementations. Set specific triggers per tag.

Week 3: Advanced Optimization

  • Day 14: Liquid audit using Theme Inspector. Fix the highest-TTFB Liquid issue first.
  • Day 15: Font optimization - limit weights, add font-display swap, add preload.
  • Day 16: LCP image preload with imagesrcset and fetchpriority.
  • Day 17: Critical CSS inline, async full stylesheet load, preconnects.
  • Day 18: Passive event listeners on all scroll and touch handlers.

Week 4: Verification

  • Three PageSpeed tests per page type.
  • Real device test on mid-range Android over 4G.
  • Search Console Core Web Vitals check after 28 days.
  • Set up Lighthouse CI before every future theme publish.

Summary

A mobile PageSpeed score improvement from 31 to 79, all Core Web Vitals moving from Poor to Good, 87 percent reduction in page weight, and $26,900 additional monthly mobile revenue. Achieved in 18 days, 46 developer hours, with a net reduction in monthly app spend.

The three changes that drove the most score improvement: image optimization and slider replacement (+18 points), app restriction and TBT reduction (+12 to 14 points per page), and the Liquid navigation fix combined with critical CSS (+8 to 10 points per page). Everything else - fonts, preloads, passive listeners, preconnects - contributed the final 10 points that pushed scores from the mid-60s into the upper 70s.

The path from a broken store to a fast one is not mysterious. It is an audit, a prioritized fix list, a week of implementation, a week of advanced optimization, and ongoing monitoring to preserve what was built. Every store that looks like this one did can reach similar results by following the same sequence in the same order.

For stores looking to systematically work through each optimization layer with Shopify-native tooling, Ecom: Page Speed Expert handles image optimization, script management, and performance monitoring - covering the image and script layers that account for the largest portion of score gains in this case study. The work is available to anyone willing to do it systematically.
Back to blog

Frequently Asked Questions


For a store starting at 1.2% mobile conversion with 8-second LCP, yes. The conversion rate improvement reflects two compounding factors: faster load time reducing bounce, and the slider removal improving above-fold clarity. Stores starting closer to industry average conversion rates (2 to 3%) will see smaller percentage improvements from speed alone, though the absolute gains are still meaningful.


The key is the audit meeting before any changes. Present the audit data — script sizes, page impact, usage data — to all stakeholders simultaneously. Build agreement on what to remove before removing anything. The A/B testing tool incident in this project happened specifically because this step was skipped for one app.


Partially. Image optimization (conversion, compression, lazy loading via theme settings) and app removal are accessible without code access. Page-specific Liquid conditionals and critical CSS extraction require theme code editing. Tools like Ecom: Page Speed Expert cover the image optimization and script management layer for stores without developer access, which typically accounts for the largest portion of score gains.


Without monitoring, stores typically regress within 6 to 12 months as new apps are installed and new content is added. The monitoring setup implemented after this project (monthly PageSpeed checks, Lighthouse CI before theme publishes, Search Console review) is designed to catch regressions within 48 hours rather than after months of degradation.


Two things would have added 5 to 8 more points: migrating from Yotpo to a lighter review app (estimated 3 to 4 points from reduced script weight) and implementing speculative prerendering for the cart page. Both were identified during the project and scheduled as subsequent work outside the 3-week window.