App performance guidelines
Performance is an important factor for merchants when they choose an app for their online store. When you build an app, you should build with performance in mind.
Optimizing your app for performance is key to the success of the merchants that you support and to the experiences of their customers. Performance directly influences conversion rates, repeat business, and search engine rankings.
Optimizing for performanceAnchor link to section titled "Optimizing for performance"
Consider the following best practices for optimizing the performance of your app.
Optimize your OAuth flowAnchor link to section titled "Optimize your OAuth flow"
Because OAuth is the first interaction that merchants have with your app UI, you should make sure that it's a positive experience. Follow these best practices for optimizing your OAuth performance to make your app authorization process smoother, faster, and more polished.
To learn how to implement OAuth in your app, refer to Getting started with OAuth. To learn how to update your existing OAuth flow to follow these best practices, refer to Update your embedded app OAuth flow.
Use Shopify templates and librariesAnchor link to section titled "Use Shopify templates and libraries"
Shopify offers app templates that already have OAuth implemented, and API libraries that include methods that simplify the implementation process. Using these templates or libraries helps to ensure that your implementation is complete, and that your app follows our OAuth best practices.
You can build an app using a Shopify app template by initializing an app using Shopify CLI. For more information, refer to Create an app.
If you don't want to use an app template, then you can use the same API libraries that the templates use to implement OAuth in your own app. To learn more, refer to Getting started with OAuth.
Conditionally escape your embedded app iframeAnchor link to section titled "Conditionally escape your embedded app iframe"
This best practice applies to embedded apps only.
For merchants to grant permission for your app to access sensitive data, your app needs to redirect to the OAuth grant screen:
Embedded apps might render inside an iframe. The grant screen won't render in the iframe due to
X-Frame-Options: DENY restrictions on the page, so you need to escape the iframe before redirecting.
You should only attempt to escape the iframe if the iframe exists. This avoids unnecessary HTTP redirects and requests, which increase load time and can cause screen flicker. To detect the presence of an iframe, check the request query parameters for an
embedded parameter with a value of
For more information about detecting and escaping an iframe, refer to Getting started with OAuth.
Request new tokens before rendering the UI, and only when neededAnchor link to section titled "Request new tokens before rendering the UI, and only when needed"
Your app might need to request a new token for a store for the following reasons:
- Your app doesn't have a token for the shop.
- Your app uses online tokens and the token for that shop has expired.
- Your app has a token for that shop, but it was created before you rotated the app's secret.
- Your app has a token for that shop, but your app now requires scopes that differ from the scopes granted with that token.
If any of these conditions are true, then your app should request a new token by redirecting to the grant screen instead of your app UI. This avoids users having to load the app UI before being redirected to the OAuth grant screen.
If none of these conditions are true, then the app should avoid requesting new tokens. These requests increase the time the app takes to load.
For more information about this logic, and how to implement it using Shopify API libraries, refer to Getting started with OAuth.
Load Shopify App Bridge from your app bundle for redirectsAnchor link to section titled "Load Shopify App Bridge from your app bundle for redirects"
Shopify offers an option to load Shopify App Bridge from Shopify CDN. However, for optimal performance, you should load App Bridge from your app bundle instead. Loading Shopify App Bridge from your app bundle increases the chance that the user’s browser can attempt to access this code from the cache. This means that users need to download less code and your app is more performant overall.
For an example of loading Shopify App Bridge from the app bundle, refer to this page in the Node app template.
Perform a server-side redirect to your embedded appAnchor link to section titled "Perform a server-side redirect to your embedded app"
This best practice applies to embedded apps only.
If your embedded app doesn't need to get a new OAuth token, and the app isn't being displayed in an iframe, then you should redirect the user to the embedded app URL so they can view your app.
You should perform a server-side 3xx redirect to the embedded app URL, rather than a client-side redirect that uses Shopify App Bridge. A server-side redirect is faster, and avoids the multiple page loads that occur during an App Bridge redirect. These page loads appear as screen flicker to the user.
To learn when to perform this redirect, and how to build and redirect to the embedded app URL, refer to Getting started with OAuth.
Include a viewport meta tagAnchor link to section titled "Include a viewport meta tag"
If your app can be embedded, then it might be rendered in a WebView when it's accessed from the Shopify mobile app. To define the scale at which your app is rendered on initial load, you should add a meta tag to the HTML file that serves your UI.
If you don't add this meta tag, then Shopify injects it for you. This ensures that merchants can use your app on mobile devices, but it results in your app UI rendering twice: once zoomed out, and once at the correct scale.
Use theme app extensionsAnchor link to section titled "Use theme app extensions"
Theme app extensions allow developers to extend themes in a way that protects theme code integrity and provides better app development and merchant experiences.
Apps built in the theme app extension framework don't edit theme code, which decreases the risk of introducing breaking changes to the theme, makes it easier to iterate on the content of the integration, and provides for a better merchant experience.
All files inside the
assets/ folder are automatically served from Shopify's CDN for fast, reliable asset delivery. Reference your assets by using either the
stylesheet schema attributes or using the
asset_img_url Liquid URL filters.
For app embed blocks, take advantage of their ability to only load scripts on specific pages.
Avoid parser-blocking scriptsAnchor link to section titled "Avoid parser-blocking scripts"
Parser-blocking scripts block the construction and rendering of the DOM until the script is loaded, parsed, and executed. They also create congestion on the network and significantly delay page rendering. This impacts metrics like First Contentful Paint and Largest Contentful Paint. You should use
async attributes on script tags to avoid this.
If the order of execution of the script tags matters, then use
If the order of execution doesn't matter, then use
Host assets on Shopify serversAnchor link to section titled "Host assets on Shopify servers"
Deliver as much as you can from the Shopify content delivery network (CDN). Using the same host for your assets avoids unnecessary HTTP connections and allows the server to prioritize delivery of blocking resources using HTTP/2 prioritization.
In a Shopify context, you can do this by using the
AssetREST Admin API resource to host your static files on Shopify's servers and have them delivered by our globally available CDN.
CDNs are accelerated web servers with built-in caching, compression, fast performance, and global distribution. Using Shopify’s CDN also reduces network congestion.
Reduce your dependency on external frameworks and librariesAnchor link to section titled "Reduce your dependency on external frameworks and libraries"
Frameworks such as React, Angular, and Vue, and large utility libraries such as jQuery have significant performance costs. A store's load time is degraded even further when multiple apps try to install the same framework multiple times on the same store.
Avoid introducing polyfill libraries for very old browsers (anything that doesn't support
await). If you use a browserslist, then you can target browsers with a > 1% marketshare.
Load non-critical resources on interactionAnchor link to section titled "Load non-critical resources on interaction"
Your page might contain code for a component or resource that isn't always used. You can load these resources using an import on interaction pattern to avoid loading, parsing, and executing unnecessary code.
Minimize your bundle sizeAnchor link to section titled "Minimize your bundle size"
Browsers can't render a page until the stylesheets are downloaded, parsed, and applied. Inline script tags run only after the stylesheets are loaded. When a remote stylesheet is included before an inline script tag, the stylesheet blocks the script tag from running.
Always include the inline script tags before the stylesheets, like in the following example:
Testing for performanceAnchor link to section titled "Testing for performance"
The tool used by Shopify to test app performance is Lighthouse. Lighthouse is an open-source, automated tool for improving the quality of web pages. It's available in the Developer Tools panel of Google Chrome, so you can test your app directly in the browser.
When you submit an app to the Shopify App Store, the app's tested on a benchmark shop to determine its performance score. To be published in the Shopify App Store, your app must not reduce Lighthouse performance scores by more than 10%.
Test your app in Google ChromeAnchor link to section titled "Test your app in Google Chrome"
- Start with a clean install of a supported Shopify theme, such as Express, without your app or any other apps installed.
- From the home page of your test store, open Developer Tools in Chrome (View > Developer > Developer Tools).
- In Developer Tools, click the Lighthouse tab.
Select Mobile from the device list, then click Generate Report.
Write down the performance score out of 100. This is your starting score.
Install your app on your test store and verify that it loads correctly.
Go to the Lighthouse tab, and click the Generate Report button.
Write down the new performance score. This is your ending score.
Divide your ending score by your starting score. The result is your app's performance ratio.
For example, if your starting score was 84, and your ending score was 72, then you would calculate 72 / 84 to see that your app’s performance ratio is 0.85.
- Learn how to submit your app to the Shopify App Store.