DEV Community

Cover image for The Full-Stack Shopify Performance Checklist: Speed, Conversions, and Custom Development Done Right
Kateryna Sharuda
Kateryna Sharuda

Posted on

The Full-Stack Shopify Performance Checklist: Speed, Conversions, and Custom Development Done Right

You launch the store. Design looks solid, photography is clean, copy does its job. Then someone runs Google PageSpeed Insights on mobile and the score comes back at 41. It's a familiar situation, and it's almost never caused by one thing.

Shopify performance is a layered problem. The theme you picked, the twelve apps installed over eighteen months, the custom JS a contractor dropped in last spring, the Liquid templates doing quiet heavy lifting on every request. Each decision stacks on top of the last. Some of those decisions help; a lot of them don't. And the frustrating part is that nothing announces itself as the culprit until you actually measure.

This checklist goes through each layer in sequence, starting at the server and working outward to the browser, so you know exactly where to look before you start changing things.

Start with What Shopify Controls (and What It Doesn't)

Shopify handles hosting, CDN delivery through Fastly, HTTP/2, and automatic asset minification. That foundation is genuinely good. It also means a meaningful chunk of your total load time, roughly 30% depending on your server response baseline, is not something you can touch. Spending time there is wasted effort.

The part you can control is everything that runs in the browser and gets processed before it: images, JavaScript, app scripts, Liquid render logic, and how your theme manages the critical rendering path. That 70% is where nearly all the real gains live.

Liquid Rendering: The Cost You Won't See in DevTools

Liquid executes on the server, so its overhead doesn't appear in your Network tab. It shows up as Time to First Byte. Stores with sluggish TTFB are almost always doing too much work in templates: nested for loops iterating over large collections, redundant metafield calls, render tags invoked multiple times for the same snippet across a single page load.

A few things worth checking directly:

  • Flatten nested loops wherever the data structure allows it
  • Use capture blocks to cache expensive Liquid calculations rather than recalculating them per render
  • Set sensible collection page sizes; loading 50+ products in a single template pass is a consistent TTFB killer
  • Audit theme.liquid for logic blocks that fire on every request regardless of which template is active

The Shopify Theme Inspector for Chrome, a free extension Shopify publishes, breaks down render time by Liquid tag. Run it on product and collection pages first. Those two templates consistently account for the most recoverable time.

Image Delivery: The Fastest Win, Usually Left on the Table

Images make up somewhere between 50% and 80% of total page weight on a typical Shopify store. Shopify's image CDN handles resizing and format conversion well, but only if the inputs going in are sensible.

Common mistakes that show up on almost every audit:

  • Source files uploaded at 3,000 or 4,000px wide when the theme renders them at 600px; Shopify resizes on the fly but still processes the full original
  • img_url: 'master' used in templates instead of a declared target size like img_url: '1200x'
  • Missing fetchpriority="high" on the LCP element, which is almost always the hero image or the first product photo
  • No loading="lazy" attribute on anything below the fold

The fetchpriority attribute gets skipped a lot because it's relatively new. What it does is tell the browser to request that specific image before other resources compete for bandwidth. On a product page where the hero image is the LCP, adding this one attribute routinely shaves 200 to 400 milliseconds off real-world LCP scores.

The App Audit Nobody Wants to Do (But Always Pays Off)

Third-party apps cause more performance regression on mature Shopify stores than any other single factor. Not because the apps themselves are poorly built, but because each one injects its own JavaScript and CSS into every page by default, whether or not that page has anything to do with the app's functionality.

A review widget loading on your FAQ page. A loyalty script firing on your blog posts. Neither does anything useful there; both add weight.

The audit itself doesn't take long:

  1. Open Chrome DevTools, find the Coverage tab (Shift+Ctrl+P, type "Coverage"), reload the page
  2. Look for JavaScript files in the 80-100% unused range; those are your candidates
  3. Match those files back to your app list to identify ownership
  4. Check each app's settings for page-specific loading options; more apps support this than merchants realize, it's just not enabled by default

Where an app can't be restricted to specific page types, ask whether the underlying functionality could be handled natively. Metafields and metaobjects now cover territory that once required dedicated apps. Online Store 2.0 sections handle display logic that previously needed a page builder. Less JavaScript shipped is faster than any amount of deferred or async loading.

Core Web Vitals: The Three Numbers That Actually Affect Rankings

Google's page experience signals pull from CrUX field data, not from Lighthouse lab scores. That gap matters more than most people realize. A store can hit 85 in Lighthouse on a fast laptop and still carry poor field scores if real users are on mid-range Android devices with variable connections.

The three metrics: Largest Contentful Paint (LCP), Interaction to Next Paint (INP, which replaced First Input Delay in 2024), and Cumulative Layout Shift (CLS). Each one has a different root cause.

The technical fixes differ by metric: LCP usually points to images or render-blocking resources, INP to synchronous JavaScript, and CLS to late-loading fonts or app blocks injecting content above existing elements. A practical starting point is to improve core web vitals on Shopify by working through each metric separately rather than chasing a single PageSpeed score.

CLS deserves a specific callout because it trips up developers who think they've handled it. Font loading is the most consistent culprit on Shopify stores. Setting font-display: optional in your theme CSS tells the browser not to swap fonts in after the initial paint, which eliminates layout shift from that source entirely. It's a one-line change; it's underused; it works.

Checkout Performance: The Layer Where Slowdowns Cost Real Money

Every page upstream of checkout exists to move someone toward a purchase. Friction there is a problem. Friction at checkout is a revenue problem.

Shopify's hosted checkout is fast out of the box. The performance risks come from what gets added to it: third-party scripts through checkout.liquid (deprecated on standard plans, still present on older Plus setups), checkout UI extensions that aren't written with care, and order status pages carrying custom code that nobody's reviewed since it was written.

If you're on Shopify Plus and using Checkout Extensibility, these extensions run in a sandboxed environment, which does constrain their performance impact. That's a good default. But sandboxed doesn't mean free: loading external fonts inside an extension, fetching uncached data on mount, or building unnecessarily deep component trees all add delay that shows up in field data.

For stores on standard plans, keeping checkout clean is the main lever. No scripts that aren't directly serving the checkout flow, no custom CSS overriding Shopify's own optimized styles, no app embeds that exist out of habit rather than necessity.

When Custom Development Makes More Sense Than More Apps

At some point in a store's growth, the cost of bridging the gap between what apps offer and what the business needs starts to exceed the cost of building the right thing. Sometimes you're paying monthly fees for four or five apps that together approximate something a single custom Liquid section or a properly scoped Shopify Function could handle more reliably, with less JavaScript in the browser.

That's not a knock on apps. Apps are often exactly the right answer. The question is whether the tool still fits the problem.

Custom development tends to pay for itself when:

  • Discount and pricing logic requires multiple apps chained together, each with its own execution order and failure mode
  • The product data model has structured relationships that flat metafields can't express without workarounds
  • Checkout behavior (validation rules, custom upsells, shipping logic) doesn't map to anything available off the shelf

If you're maintaining more than three apps to solve what feels like one problem, that's usually a signal the solution belongs in code rather than configuration. Shopify web development services handle exactly that kind of consolidation, and the result tends to be faster, cheaper to run, and easier to debug.

Monitoring After Launch: Treat It Like a Recurring Task, Not a Checkbox

A store that ships at 90 on PageSpeed will drift toward 65 within six months if nobody's watching. App installs add weight. Theme updates introduce regressions. Seasonal campaigns bring new scripts that never get removed. Performance debt accumulates quietly.

A lightweight monitoring setup that actually gets used:

  • Google Search Console, Core Web Vitals report, reviewed monthly for URL-level changes
  • CrUX field data to track real-user experience rather than synthetic lab scores
  • A saved Lighthouse baseline after each significant theme update; Treo.sh and SpeedCurve both automate this without much overhead
  • A quarterly run of the Coverage tab audit to catch app script sprawl before it compounds

A 20-minute quarterly audit is a lot cheaper than diagnosing a 35-point score drop that accumulated across six months of small decisions.

Summing It Up

Shopify performance is not a one-time project. It's a set of ongoing decisions across every layer of the stack, from Liquid rendering at the server to real-user field data in CrUX. Start with images and Liquid since those two areas return the most gain per hour of work. Add the app audit once the basics are stable. Then address Core Web Vitals using field data, not lab scores.

Custom development earns its place when the apps-and-configuration path stops being cost-effective. Monitoring keeps the work from quietly unraveling after launch. Fix the layers in order, keep reviewing them on a schedule, and the scores follow.

Top comments (0)