Ayan Ali.
8 min readUpdated

How to Speed Up a Shopify Store Without Apps

Most Shopify speed problems come from images, scripts and installed apps, and none of them need another app to fix. Here is the order to work in, with the Liquid to do it.

ShopifyPerformanceLiquid
A stack of heavy compressed slabs on the left resolving into a single weightless lime-edged plate on the right, with the Shopify logo embossed on the leading slab.

Short answer: measure first, then work through five fixes in order: remove or replace unused apps, load the first-screen image correctly, defer non-essential scripts, trim fonts, and simplify heavy Liquid loops. Each is a theme change, so no speed-booster app is involved. The Liquid for the image fix and the script fix is below. Checked against Shopify's developer documentation, October 2026.

How do I find out why my Shopify store is slow?

Start with field data for your slowest important page, which is usually the home page, a collection page or a product page. Run it through PageSpeed Insights and read the real-user (field) section before the lab score, since field data reflects what visitors experienced over the last 28 days.

Google's "good" thresholds are LCP of 2.5 seconds or less, INP of 200 milliseconds or less and CLS of 0.1 or less. Note which metric fails, because the fix differs: a slow LCP points to images or render-blocking resources, a high CLS points to missing image dimensions or font swapping, and a high INP points to heavy JavaScript. For a deeper walk-through of each metric, see Core Web Vitals for Shopify Liquid themes.

Which apps should I remove first?

Remove apps that do one small visible job, since those are the easiest to replace with a theme section. Common examples are announcement bars, countdown timers, sticky add-to-cart buttons, size charts, simple pop-ups and color swatches. Each of these can be a Liquid section or a few lines of CSS.

Keep apps that do work the theme cannot do, such as payments, subscriptions, reviews with moderation, and email. For each remaining app, open your browser's Network tab, filter by JavaScript, and check how many requests and how many kilobytes the app adds. Shopify's own Built for Shopify program requires listed apps not to reduce a store's Lighthouse performance score by more than ten points, so an app that is not in that program has no such guarantee.

| App type | Replace with | Caveat | |---|---|---| | Announcement bar | Theme section | None | | Color swatches | Linked-product swatches in Liquid (how) | Needs one product per color | | Size chart | Page or metaobject rendered in a modal | Needs content upkeep | | Sticky add-to-cart | Theme section plus CSS | Test on mobile | | Landing-page builder | Custom Liquid sections | Needs a developer | | Chat widget | Keep, but load it after the page | Load on click or after a delay |

How do I uninstall an app without leaving junk in my theme?

Duplicate your live theme first, then uninstall the app, then search the duplicate for the app's name. Shopify's documentation says uninstalling apps often leaves code edits, which it calls ghost code, behind in the theme, and that this can cause quality and performance issues.

Search the theme code editor for the app's name, for render calls to its snippets, and for <script> tags that point at its domain. Delete what is clearly the app's, check the preview on the home, collection, product and cart pages, then publish the duplicate. Apps built with theme app extensions do not edit theme code, so they tend to leave nothing behind, but older apps often do.

How do I fix a slow hero image on Shopify?

Load the first-screen image eagerly, mark it as high priority, and use Shopify's image_tag filter. Shopify's performance documentation says never to lazy-load the LCP image, because loading="lazy" deprioritizes it and delays the download until after the browser runs an IntersectionObserver check.

{%- liquid
  if section.index == 1
    assign loading = 'eager'
    assign priority = 'high'
  else
    assign loading = 'lazy'
    assign priority = 'auto'
  endif
-%}

{{ section.settings.image
  | image_url: width: 1600
  | image_tag:
      loading: loading,
      fetchpriority: priority,
      widths: '800, 1200, 1600',
      sizes: '100vw' }}

This code uses section.index so only the first section on the page loads eagerly. The image_tag filter adds a srcset and the width and height attributes, which prevents layout shift. Avoid CSS background-image for the hero, since the browser's preload scanner finds an <img> earlier. Do not hide the hero behind a fade-in animation either, because animations delay the LCP event even after the image has loaded.

How do I lazy-load collection images correctly?

Load the first few product cards eagerly and the rest lazily. A collection page can render up to 50 products in its first section, and only the first row is visible without scrolling. Shopify's docs show using forloop.index for this.

{% for product in collection.products %}
  {%- liquid
    if forloop.index <= 4
      assign image_loading = 'eager'
    else
      assign image_loading = 'lazy'
    endif
  -%}
  {{ product.featured_image
    | image_url: width: 400
    | image_tag: loading: image_loading, widths: '200, 300, 400',
        sizes: '(min-width: 1200px) calc(25vw - 2rem), (min-width: 768px) calc(33vw - 2rem), calc(50vw - 2rem)' }}
{% endfor %}

If your theme uses a JavaScript lazy-loading library such as lazysizes, remove it. Those libraries replace src with data-src, which hides the image URL from the preload scanner until JavaScript runs. Put src back and add loading="lazy" to images below the first screen.

How do I defer scripts in a Shopify theme?

Add the defer attribute to your own non-critical scripts, and write the tag by hand because the script_tag filter does not support defer or async.

<script src="{{ 'theme-interactions.js' | asset_url }}" defer></script>

Defer analytics, chat widgets and anything that is not needed for the first paint. Shopify's docs give a pattern for chat widgets: show a lightweight placeholder button and load the real widget on click, or after a delay such as ten seconds. Two things cannot be deferred: content_for_header, which Shopify injects, and A/B testing anti-flicker snippets, which must load synchronously by design.

How do fonts slow down a Shopify store?

A web font adds a download to the critical path, and a font swap can shift the layout. The fastest option is system fonts, which need no download and cause no swap. If your brand needs a custom font, self-host a WOFF2 file from your theme assets with font-display: swap.

@font-face {
  font-family: "Brand Font";
  src: url("brand-font.woff2") format("woff2");
  font-display: swap;
}

Add a fallback @font-face with size-adjust values measured for your font, so the swap does not move text. Shopify's docs point to tools such as Fontaine and Capsize for generating those values. Preload at most one or two resources, since overusing preload competes with the browser's own prioritization and can slow the page.

Why is my Shopify server response time slow?

Nested Liquid loops are the most common cause. Shopify's performance documentation says loops nested across products, variants or options grow quadratically with catalog size, so a theme that is fast on 10 products can be slow on 100.

Look for loops inside loops in your collection and product templates. Also avoid rendering every variant of a product, since product.variants returns at most 250 variants and Shopify recommends product.options_with_values for building option pickers instead. Move work out of the first render when you can, such as loading related products after the page paints.

What did I do on real stores?

I build storefront sections in Liquid instead of installing page-builder apps. Zaiqa uses a premium theme with almost all sections custom coded, and Naturabites uses custom Liquid sections for the landing, about and product pages. On BAOBAB, the color-swatch variant picker was custom coded rather than added through an app.

I have not published before-and-after speed numbers for these stores, and I will not invent them. See the Naturabites, Zaiqa and BAOBAB case studies for the work itself.

When should I get help?

Get help when the fix needs theme code edits you are not comfortable making, or when the audit shows apps that must be replaced with custom sections. A good first step is a list of installed apps with the JavaScript each one adds.

If you want an app and speed audit on your store, see my Shopify development services or get in touch with your store URL.

Sources

Frequently asked questions

Can I speed up a Shopify store without installing a speed app?

Yes. The biggest wins are usually removing unused apps, loading the hero image correctly, deferring non-essential scripts and trimming fonts. All of these are theme changes, not app installs.

Which Core Web Vitals numbers should I aim for?

Google's 'good' thresholds are LCP of 2.5 seconds or less, INP of 200 milliseconds or less and CLS of 0.1 or less. Shopify's Built for Shopify requirements use the same CLS and INP figures.

Should I lazy-load every image on a Shopify store?

No. Lazy-load images below the first screen, and load the first-screen image eagerly. Shopify's performance docs call lazy-loading the main above-the-fold image one of the most common and damaging mistakes in themes.

Does uninstalling an app remove all of its code from my theme?

Not always. Shopify's developer documentation says uninstalling apps often leaves code edits, called ghost code, behind in the theme. Search your theme files for the app's name after you uninstall.

Can I defer every script on my store?

No. Shopify injects content_for_header and it cannot be deferred. You can defer your own theme scripts, analytics and chat widgets.

Store loading slowly?

I fix Shopify performance by hand — images, scripts, app bloat, theme code — without installing another app to fix the apps. Send me your store URL and I'll tell you what is actually costing you.

Read next

How to Add an AI Chatbot to Shopify Grounded in Your Product Catalogue
A frosted speech-bubble form above a grid of product boxes, connected by thin lime lines, with the Shopify logo set into the floor and the OpenAI logo on the bubble.
Shopify

How to Add an AI Chatbot to Shopify Grounded in Your Product Catalogue

A Shopify chatbot that does not invent products needs four parts: a synced catalogue index, retrieval, a grounded prompt, and a Liquid section that talks to your backend. Here is each part.

Read
How to Build an AI Product Finder Section for Shopify
A wide field of dark cubes receding into shadow with a narrow lime light picking out exactly three, and the Shopify logo on a plate in the foreground.
Shopify

How to Build an AI Product Finder Section for Shopify

A product finder takes 'a waterproof jacket for light hiking under $150' and returns matching products. It needs vector search and filters, and it does not need a chat model.

Read
How to Make Shopify Color Swatches Link to Separate Product Pages
Five matte spheres in a row, each linked by a thin lime line to its own separate product panel below, with the Shopify logo on a plinth in the foreground.
Shopify

How to Make Shopify Color Swatches Link to Separate Product Pages

A swatch that opens a different product page needs one product per color, a metaobject that groups them, and a short Liquid snippet. Here is the full build, and when not to bother.

Read

Got a store or a build in mind?

Tell me what you're trying to ship — a Shopify section, a full storefront, a chatbot, or a web app. I'll tell you what it takes, honestly, before you commit.

ayanrjpoot@gmail.com