App performance recommendations

Before you upload your app to the Shopify App Store, you must test your app's performance to verify that it doesn't reduce Lighthouse performance scores by more than 10%. To ensure that your app meets the specified requirements, review the best practices that are described in this topic.

Replace parser-blocking script tags with non-blocking tags

When you build your app, you should use defer or async attributes on script tags. If you don't include these attributes, then the parser is blocked until the scripts are loaded, parsed, and executed. When the parser is blocked, it delays the construction of the DOM, creates congestion on the network by downloading JavaScript files before any other assets, and significantly delays the initial rendering of the page.

If the order of execution of the script tags matters, then use defer.

<script src="https://cdn.shopify.com/app-code.js" defer></script>
<script src="app-code.js" defer></script>

If the order of execution doesn't matter, then you can use async.

<script src="https://cdn.shopify.com/app-code.js" async></script>
<script src="app-code.js" async></script>

Host static files on Shopify servers

Use the Asset API 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.

Avoid JavaScript frameworks

To improve your app performance, use native browser features and modern DOM APIs whenever possible. Including Javascript libraries in your package can lead to large bundle sizes, slow load times, and a poor experience for online shoppers. 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.

To verify that your app supports older browsers, you should also avoid using polyfill libraries.

Use CSS instead of JavaScript whenever possible

CSS parses and renders much faster than JavaScript, so wherever possible, you should use CSS features for building interactivity. You can find more information on the internet by searching the phrase “using css instead of JavaScript”. For example, the blog 5 things you can do with CSS instead of JavaScript by Juan Martín García.

Defer loading your JavaScript bundle entirely

Defer loading your JavaScript bundle entirely until a user interacts with the parts of your app that require the bundle. For more information, refer to The Import on Interaction pattern by Addy Osmani.

Minimize your bundle size

To ensure good performance, generally your app should inject less than 10KB of JavaScript on a page, and less than 50KB of CSS. Make sure that you optimize your bundle sizes by minimizing your code, and serving your assets with gzip or brotli compression enabled.

A store's theme is responsible for user interactivity. Your app should change the theme only slightly. If you need to inject more JavaScript, then be sure it loads without blocking the browser by following the recommendations on this page.

Include remote stylesheets after inline JavaScript tags

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.

<script>console.log('hello world')</script>
<link href="//example.com/app-css.css" rel="stylesheet">