Debugging performance with metric gaps
Use your Real User Monitoring (RUM) data to diagnose performance problems before you open any lab testing tool. As the Shopify Performance Team puts it: "The first step to debugging a slow site should not be to open up a lab-based testing tool... Instead, we should be looking at our real user monitoring (RUM) data to identify and prioritize our biggest opportunities." The primary loading metrics, TTFB, FCP, and LCP, share the same starting point (navigation start), so the gaps between them reveal where problems are concentrated.
Anchor to Visualizing the gapsVisualizing the gaps
Use a RUM tool that provides a distribution view, like the Shopify Web Performance Dashboard or the free TREO Site Speed tool:
- Visit
https://treo.sh/sitespeed. - Enter your domain.
- Toggle to the Distributions view.
- Look at the stacked bar charts.
Good performance shows mostly green across all three metrics. Poor performance shows yellow or red. Comparing the three reveals where issues concentrate. Analyze by page type (home, product, and collection) and device (mobile and desktop) separately for better specificity.
Anchor to How to find your gapsHow to find your gaps
Work from field data to a single suspect phase before you open a lab tool:
- Pick one page type and one device category. A home page on mobile and a product page on desktop are different problems with different fixes.
- Read TTFB, FCP, and LCP for that segment at the same percentile. Use the Shopify Web Performance Dashboard for your own store, or TREO Site Speed and PageSpeed Insights for CrUX data on any public domain.
- Subtract to get the three gaps: TTFB itself, then FCP minus TTFB, then LCP minus FCP.
- Take the largest gap as your suspect phase, and match it to a pattern below.
- Reproduce the phase in a lab tool. Configure WebPageTest or the Chrome DevTools Performance panel with a device, connection, and location that resemble the segment you picked, then read the waterfall for that phase only.
- Fix one thing, then confirm the gap closed in field data before moving to the next phase.
If you can't get field data for a page, because it's new or low-traffic, then measure it in the lab, but treat the numbers as a hypothesis rather than a baseline. See Lab vs. field data for why the two disagree.
Anchor to Gap patternsGap patterns
Each diagram below is a schematic timeline, not a measurement. All three metrics start at navigation start, so the distance between the markers is the gap you're diagnosing:
Anchor to Pattern 1: Slow TTFB, then quick FCP and LCPPattern 1: Slow TTFB, then quick FCP and LCP
Problem area: server response or complex Liquid rendering. The browser can't start work it hasn't received.
Common causes on Shopify storefronts:
- Expensive Liquid: deeply nested loops, filters or metafield lookups repeated inside loops, and nested
rendercalls. - Overfetching: paginating too deeply, or loading every variant when the page shows one.
- A proxy in front of the Shopify CDN, which adds a network hop to every request and can defeat edge caching.
- App proxies or server-side app logic in the request path.
Where to go next:
- Liquid performance patterns
- Avoid deeply nested Liquid loops
- Move metafield access outside loops
- Limit pagination depth
- Avoid request proxies
Anchor to Pattern 2: Fast TTFB, slow FCPPattern 2: Fast TTFB, slow FCP
Problem area: the HTML arrived quickly, but something is standing between it and the first paint.
Common causes on Shopify storefronts:
- Render-blocking stylesheets and synchronous scripts in
theme.liquid, including app-injected tags you didn't add. - Anti-flicker snippets from A/B testing tools, which deliberately hide the page until their script runs.
- Too many separate stylesheets, so the browser waits on a long chain of requests.
- A large DOM before the first paint, most often a mega menu duplicated for mobile and desktop.
- Blocking requests to third-party origins that need a fresh DNS lookup, TLS handshake, and connection.
Where to go next:
- Defer non-critical scripts
- Load critical CSS synchronously
- Reduce stylesheet count
- Manage A/B testing impact
- Remove or optimize apps causing render-blocking issues
- Merge duplicate mobile and desktop menus into one
- Warm up third-party connections early with
preconnect
Anchor to Pattern 3: Fast TTFB and FCP, slow LCPPattern 3: Fast TTFB and FCP, slow LCP
Problem area: the page paints something quickly, but the largest element arrives late. Split this gap in two: the browser either found the resource late (a discovery problem) or found it on time and displayed it late (a render problem).
Common causes on Shopify storefronts:
- The LCP image carries
loading="lazy", often from a theme setting or a section that lazy-loads everything by default. - The LCP image is a CSS background, so the preload scanner can't discover it until the stylesheet is parsed.
- JavaScript renders the LCP element, or the Section Rendering API fetches it after the initial paint.
- A fade-in, carousel transition, or scroll animation hides the image after it has downloaded.
- A dialog, cookie banner, or email capture becomes the LCP element instead of your hero.
- The image is much larger than the space it fills, because you didn't set
widthsandsizes.
Where to go next:
- Never lazy-load the LCP image
- Mark the LCP image with
fetchpriority="high" - Don't use CSS
background-imagefor LCP content - Render essential content server-side
- Don't hide the LCP image behind animations
- Prevent dialogs from hijacking LCP
- Serve correctly sized images with
srcsetandsizes
Anchor to Pattern 4: Multiple gapsPattern 4: Multiple gaps
Indicates: multiple problems need addressing.
Prioritization: Fix FCP-related issues first, because they also impact LCP. However, if you see an obvious and easy-to-fix LCP issue, such as lazy loading the LCP image, fix that first.
When every phase is slow, suspect a single cause with reach across all of them before you plan three separate projects. A proxy in front of the Shopify CDN, a heavy script that every page loads, or a third-party tool that both blocks rendering and delays images can produce this shape on its own. Audit what's shared across page types first. See Audit and remove third-party scripts and Finding and ranking your worst JavaScript offenders.
Anchor to ReferencesReferences
- Debugging common causes for slow loading in Shopify Liquid storefronts
- Lab vs. field data
- Build a sustainable performance practice
- Defer non-critical scripts
- Never lazy-load the LCP image
- Testing for performance
- Core Web Vitals thresholds