React Native has seen a great market adoption since its inception and has come a long way in terms of creating super fast and performant apps. However, keeping apps performant is a marathon and it gets harder as we scale our apps. To keep apps performant, constant monitoring and optimization is necessary.
There are many factors that affect the performance of an app. Some may impact app startup time while others may impact the app’s runtime performance. In this post, we will go through some of the tools and techniques that can help you improve and maintain the performance of your React Native apps.
How important is performance?Performance in today’s world isn’t just the cherry on top of the cake. It is a necessity. Recent studies and statistics show that 70% of users will abandon an app in favor of a competitor, if it loads slowly. According to a study by Google, even the slightest delay in app loading can lead to a significant drop in user engagement. Or, on the flip side, if an app loads fast, it can lead to a significant increase in conversions and better user retention.
With the rise of mobile apps, the competition is getting tougher and tougher, studies show that nearly one in every two apps are uninstalled within the first month of installation. Poor performance can be a deal breaker for your app.
Tools & techniques to improve performanceHere’s some of the tools and techniques that can help you improve the performance of your React Native apps.
Enable HermesHermes is a new JavaScript engine optimized for running React Native apps; its goal is to improve app performance. It converts JS code to bytecode that enables faster startup time. Also, it does better memory management through improved garbage collection to reduce memory usage and improve runtime performance.
Impact: Better Startup time, lesser memory usage, better runtime performance.
New ArchitectureReact Native went through a massive architectural overhaul in the past couple of years, resulting in a whole new architecture based on Fabric and TurboModules. I discussed this new architecture in another post. As a recap, this new architecture mitigates one of the most critical performance bottlenecks in React Native: “the bridge”, using TurboModules. Fabric, a new rendering mechanism, brings features like view flattening, render pipeline along with React Concurrent Features to make UIs smoother and more responsive than ever before.
Impact: Better UI rendering for a smoother experience
Optimizing JS Bundle using Re.packFor large scale apps, JS bundle size can be a big concern. As the app grows, the bundle size grows as well. This can lead to slower app startup time and slower runtime performance. As most of the logic for RN apps is written in JS, optimizing the JS bundle can have a huge impact on the performance of the app.
Using Re.pack can help you create multiple chunks of JS bundle and load them on demand. This can have a direct impact on startup time, as less of the JS bundle is loaded initially. Also, this can improve runtime performance, as less of the JS bundle is loaded in memory.
Impact: Smaller app size, faster startup, better runtime performance
Graphics & ImagesTo be on top, aesthetics and visuals in apps are essential. On the performance side, it can be challenging to handle the impact that high resolution images or complex graphics can have on the app. To keep the app performant, it is important to optimize images and graphics. On the simpler side, all images in the app can be passed through an optimizer to reduce their size while keeping quality intact. While the better solution would be to break down images into more manageable chunks and render them accordingly. Here are small tricks to manage images and graphics in your app.
Impact: Better performance for images and graphics, smaller app size, lesser network cost
Optimizing large listsFor apps with large lists, it can be challenging to keep the frame rate smooth, especially when the list is scrolled. Also, when the list is scrolled, the app is more likely to run out of memory. To keep the app performant, it is important to optimize memory usage and frame rate. Here are some of the techniques that can help you optimize large lists.
getItemLayout prop to optimize memory usage. Also, use initialNumToRender and maxToRenderPerBatch props to optimize frame rate.Impact: Better performance for large lists, lesser memory usage, better frame rate
AnimationsLike graphics, animations are also a big part of great user experience. At the same time, Janky animations can be a big turn off for users. Performance of animations is one of the most critical vectors in app performance. Implementing animations in a performant way can involve some complex math and algorithms. But, even with that, it boils down to how well the implementation of animations is done on the platform. Here are tools to handle complex animations in a performant way.
Impact: Smoother animations, better user experience
AdaptabilityPerformance and adaptability go hand in hand. For a great user experience and to keep users engaged, it is important for apps to adapt to the device’s capabilities at any given time. For example, if the device is low on memory, the app should be able to adapt to it and not crash. Similarly, if the device is low on battery, the app should be able to adapt to it and not drain the battery.
Impact: Better user experience, lesser crashes, lesser battery drain
GesturesGestures are a big part of the user experience. It is important to make sure that gestures are smooth and responsive. Having lag in gestures makes the app feel unresponsive and can result in drop off. Thanks to React Native Gesture Handler, performant gestures are now easier to implement. It provides a declarative API for creating gestures and animations and coupled with Reanimated, it can be used to create complex gestures and animations.
Impact: Smoother gestures
NavigationNavigation works as the backbone of the app and can have a big impact on performance. Thanks to great libraries like React Navigation, navigation is now easier than ever. Adding React Native Screens makes navigation even more performant. Also, opting for react-navigation-native-stack instead of react-navigation-stack can bring some big performance improvements. @react-navigation/native-stack offers native performance as it leverages native APIs UINavigationController on iOS and Fragment on Android. It also offers more native UI features like large titles; though it’s not as customizable as react-navigation-stack.
Moreover, optimizing options in the tab navigator can improve memory usage and frame rate.
Impact: Better performance for navigation
Performance checks in CI/CDPerformance is a continuous process and requires constant monitoring and optimization. As we keep adding more features, it is important to make sure that performance is not compromised. It is important to have performance checks in CI/CD to ensure that performance benchmarks are not broken. Tools like React Native Reassure and Shopify’s React Native Performance are easy to integrate and can be used to run performance checks in CI/CD. These tools can give you a good idea about startup time, memory usage, frame rate, etc. and can be used to set performance benchmarks.
Parting thoughtsPerformance is a marathon and not a sprint. It is a continuous process and requires constant monitoring and optimization. In this article, we discussed some of the tools and techniques that can help you improve the performance of your React Native apps. We will be adding more tools and techniques in the future. If you have any suggestions or feedback, please feel free to add comments below.
The post How to Improve React Native Performance appeared first on Semaphore.