How Shopify Cut Its Mobile App Screen Load Times by 59%
Shopify’s merchant-facing mobile app is a high-frequency tool, so performance regressions are felt quickly. When the team noticed a slowdown after migrating to React Native in early 2023, they set concrete targets and spent the year optimizing. The results: app launch times (P75) improved by 44% and screen loads (P75) dropped by 59%.
Setting and Tracking Targets
Shopify defined its goals independent of the underlying technology. The targets were critical screens loading in under 500ms (P75) and app launch within 2s (P75). At the time, screen loads sat at 1400ms (P75) and launch took about 4 seconds.
To measure progress, the team built real-time internal dashboards with filtering by device model, OS version, and other dimensions. That allowed them to slice the data when debugging and validate each change they shipped.
Three Root Causes of Slowdown
Shopify grouped its performance issues into three categories: work done at the wrong time, unnecessary work, and underused caching.
Doing Necessary Work at the Wrong Time
Excessive initial rendering. The most common issue was rendering more than the viewport required. While UI paints 60 times per second, anything outside the visible area doesn't need to be drawn on the first frame. For example, a carousel needs at least three items for smooth scrolling, but only one needs to render immediately—the other two can be buffered.
Shopify addressed this with LazyScrollView, a component powered by FlashList, which only renders visible content during the initial render. On long screens where even half the content was hidden, this produced load time reductions of up to 50%.
Delaying non-critical data. The home screen was waiting for all its queries to finish before showing content. Shopify reworked it so that queries whose results weren't visible in the first paint could complete afterward, letting the screen appear much sooner.
Drawing elements before they are needed. Horizontal lists with 10 to 20 items were being drawn with ScrollView or FlatList, which render everything or about 10 items, respectively. Since only about three items are visible on most devices, this was pure waste. Switching to FlashList resolved the issue by using item size estimates to draw only what fits on screen.
Shopify also rewrote every screen to be a list, no matter how small. They built a set of tools called ListSource on top of FlashList that only renders visible components and automatically memoizes updates. This sped up initial renders and optimized subsequent changes through a more intuitive API than their previous “cell-by-cell” components.
Launch-time fixes. Two changes improved startup. Setting inlineRequires to true in metro.config.js cut launch time by 17%. Even with Hermes, the team found a lot of upfront code execution was avoidable; this config option is apparently easy to overlook. They also profiled native module startup, found one module taking too long to initialize, and fixed it to further reduce launch time.
Doing Unnecessary Work
Freezing background screens. As a hybrid app using both React Navigation and native navigation, Shopify noticed screens in the back stack updating for no reason during navigation. They built a solution to automatically freeze background components, which reduced navigation time by up to 70% on some screens.
Making Restyle faster. Shopify contributed optimizations to the Restyle library. The styling library created more objects than necessary, which compounded across thousands of components. The fix improved Restyle itself by 5-10%, bringing its overhead on top of vanilla React Native components down to under 2%.
Batching state updates. React Native doesn't always batch state changes, so Shopify wrote custom code to enable it by default. This change improved screen load times by an average of 15%, and up to 30% for screens that made many bridge requests before updating state.
Not Leveraging Cache to Its Fullest
The app already loaded data from cache first and fetched from the network in parallel, which helps perceived loading and is relevant for merchants who return frequently. Shopify decided to push this strategy further. Tracking showed only 50% of users were loading from cache first. A bug in the GraphQL cache was identified; fixing it increased cache hits by 20%.
To improve both cache hit rates and data relevance, the team implemented pre-warming at common trigger points for critical screens. Afterward, up to 90% of merchants saw cached data first, eliminating the network lag for those screens entirely.
Ongoing Work
Shopify treats performance as a continuous process rather than a one-time fix. The data-driven approach—setting targets, monitoring them, and applying targeted changes to rendering, execution timing, and caching—delivered major gains. The team remains committed to keeping the app as fast as possible for its merchants.



