How to Measure and Improve LCP in a Shopify Embedded App

Calendar iconOctober 7, 20266 min read

If you build Shopify apps, you have probably seen this: your app feels fast, merchants are not complaining, and yet the Partner Dashboard says your Largest Contentful Paint (LCP) is too slow for Built for Shopify.

We tried several ways to track this down. The method that worked best was also the simplest: install Google's web-vitals library, log the LCP value together with the element that produced it, and focus the fix on that one element. This guide walks through exactly how we measure and improve LCP in a Shopify embedded app.

TL;DR: Add onLCP from the web-vitals library to your app locally with reportAllChanges: true, load the app in the Shopify admin, and read which element is your LCP. Then speed up that element: prioritize or preload images, remove lazy loading, compress images, and remove anything that blocks rendering, including slow server-side queries.

What is LCP and why does it matter for Shopify apps?

LCP measures how long it takes for the largest visible element on the page to render. That element is usually a hero image, a large block of text, or a data table. Google considers an LCP of 2.5 seconds or less to be good.

Shopify uses the same threshold. According to the Built for Shopify requirements, your app's LCP must be 2.5 seconds or less to qualify for the badge.

The Built for Shopify badge brings better visibility in the Shopify App Store and more trust from merchants. A slow LCP is not just a technical score. It is a growth blocker for your app.

Why LCP is hard to fix in a Shopify embedded app

Your app can feel fast and still be measured as slow

LCP only stops counting when the largest element finishes rendering. A small header or spinner can appear instantly while a big table or image waits on a slow API call. The whole time, LCP keeps counting.

PageSpeed Insights and Lighthouse can't see your app

Google PageSpeed Insights and similar tools need a public URL. An embedded app runs inside an iframe in the Shopify admin, behind authentication. These tools cannot load your app the way a merchant sees it.

Shopify shows the score, not the cause

The Partner Dashboard tells you your LCP number, but not which element caused it. Without that information, you end up guessing: compressing random images, splitting bundles, adding caching everywhere, and hoping the number moves.

Step 1: Measure LCP and find the slow element with web-vitals

The tool we use is Google's web-vitals library. It is small and maintained by the Chrome team. It also works inside an iframe, because it runs in your app's own page.

Three things make this approach easy:

  • No production deploy needed. Run it in your local development environment while you open the app through the Shopify admin as usual.
  • The basic usage guide is enough. You don't need dashboards or an analytics endpoint.
  • You only need LCP. Skip CLS and INP for this job.

Install the library:

npm install web-vitals

Then add this near the entry point of your app's frontend:

import { onLCP } from 'web-vitals';

onCLS(console.log, {reportAllChanges: true});

Why reportAllChanges matters

While a page loads, the LCP element can change several times. First it might be a heading, then a card, then a table once the data arrives. Setting reportAllChanges: true logs every change, so you can see the whole sequence and spot the moment where the time jumps. In our projects, this sequence was often more useful than the final number.

Tips for accurate LCP measurement

  • Don't click or scroll while measuring. The browser stops recording LCP after the first user interaction. Touching the page early gives you a misleading result.
  • Hover the logged element in Chrome DevTools. The console highlights the element on the page, so you know right away what you are dealing with.
  • Treat local numbers as relative. Development builds are usually unminified and slower than production. Use local logging to find the culprit, then confirm the improvement in the Partner Dashboard after you deploy.
  • Use the attribution build for deeper analysis. The library's attribution build splits LCP time into server response, resource load delay, load duration, and render delay. It tells you not just which element is slow, but why.
Browser console logging LCP value and element in a Shopify embedded app using web-vitals

Step 2: Improve LCP by fixing that element

Once you know the LCP element, the question becomes simple: how do we get this element on screen faster? Sometimes the answer is to not load it at all on first render, or to move it outside the initial viewport. Here is what has worked for us.

How to improve LCP when the element is an image

1. Give the image high fetch priority. Add fetchpriority="high" to the image tag so the browser downloads it before other assets:

<img src="/images/banner.webp" fetchpriority="high" alt="Descriptive alt text">

Be careful: raising the priority of one asset means others wait longer. Test and measure the side effects before you ship it.

2. Preload images loaded by CSS or JavaScript. The browser can't discover a background image or a JS-inserted image until that code runs. A preload hint starts the download right away:

<link rel="preload" as="image" href="/images/banner.webp">

3. Remove lazy loading from the LCP image. loading="lazy" delays an image until it is near the viewport. That is great for images further down the page, but bad for the image that defines your LCP. Make sure your LCP image loads eagerly.

4. Compress and resize the image. Use a modern format like WebP or AVIF, and resize the image to the size it is actually displayed at, especially on smaller screens. A 2,000px image shown at 600px is wasted download time.

How to improve LCP for any element: remove what blocks it

Make sure nothing is blocking the LCP element from rendering. This is often where the biggest wins hide, and the cause is frequently not on the frontend at all.

In one of our apps, the LCP element was a simple summary block. The frontend looked fine. The real problem was a slow count query on the server: the block could not render until the database returned the total. Once we cached that count, the element loaded much faster and LCP dropped below the 2.5-second threshold.

Other common LCP blockers to check:

  • Large JavaScript bundles that must download and run before anything renders
  • Several API calls that run one after another before the main content appears
  • Web fonts that hold back text rendering
  • Heavy work during the first render that could wait until the content is visible

Checklist: how to measure and improve your Shopify app's LCP

  1. Install web-vitals locally and log LCP with reportAllChanges: true.
  2. Open your app in the Shopify admin without interacting, and note which element is reported and how the time changes.
  3. Fix that specific element: prioritize, preload, remove lazy loading, compress the image, or remove whatever blocks it, including slow server-side work.
  4. Deploy and confirm the result in the Shopify Partner Dashboard.

Measuring first saves a lot of wasted effort. In most cases, one element is responsible for most of the delay.

Frequently asked questions

What LCP score does a Shopify app need for Built for Shopify?

Your app's LCP must be 2.5 seconds or less. This matches Google's threshold for a "good" LCP score.

Can I use PageSpeed Insights to test a Shopify embedded app?

Not reliably. Embedded apps load inside an iframe in the Shopify admin and require authentication, so PageSpeed Insights cannot load them as merchants see them. Measure from inside the app with the web-vitals library instead.

Do I need to deploy web-vitals to production to find the LCP element?

No. Running it in your local development environment is enough to identify the LCP element. Deploy your fixes, then confirm the new score in the Partner Dashboard.

Why does my Shopify app feel fast but still have a slow LCP?

LCP measures the largest visible element, not the first one. If your largest element, such as a table or an image, waits on a slow API call or database query, LCP stays high even when the rest of the page appears quickly.

Need help getting your Shopify app under 2.5 seconds?

If you don't have the time or technical depth to find and fix your app's LCP, we can help. NUS Technology has built and maintained web applications since 2013, including Shopify apps and stores. We can audit your app, find what is slowing it down, and fix it.

If you want a team to keep your app fast and healthy for the long run, see our software maintenance service.

Contact us and tell us where your app stands today.

Chien Tran avatar
Author: Chien Tran
Co-founder and CEO of NUS Technology, with a background in software engineering and over 13 years of professional experience in software development and team leadership.
Share This Article
Copied!

Read More

n8n eCommerce Automation as a Multi-Tenant SaaS: Inside Our Ecom Automation Demo
Calendar iconSeptember 17, 20266 min read

n8n eCommerce Automation as a Multi-Tenant SaaS: Inside Our Ecom Automation Demo

See how we built n8n eCommerce automation into a multi-tenant SaaS: Shopify orders, Zoho stock checks, EasyPost shipping, and the architecture behind it.

Handling 500+ Professional RAW Images in the Browser Without Melting RAM
Calendar iconAugust 12, 20264 min read

Handling 500+ Professional RAW Images in the Browser Without Melting RAM

Browsers choke decoding hundreds of RAW images. See how custom decoders, DCT subsampling & viewport queuing handle 500+ photos on a 25MB budget.

Navigating Shopify's REST to GraphQL Migration with A Zero-Downtime Strategy
Calendar iconJuly 24, 20263 min read

Navigating Shopify's REST to GraphQL Migration with A Zero-Downtime Strategy

Shopify's REST API deprecation forces apps to migrate to GraphQL. Discover how our team executed a zero-downtime hybrid migration using shadow mode testing, strategic ID normalization, and phased rollouts to protect mission-critical eCommerce workflows.

Turn Insights into Action

Enjoying our articles?
Let’s have a strategic conversation about how these principles can
be applied to solve your specific business challenges.

CodeMonitorGrid with light