How to Improve Your React Native App Performance
How to Improve Your React Native App Performance
React and React Native have become extremely popular tools for building applications. In this article, we address some of the performance issues of React.
Join the DZone community and get the full member experience.Join For Free
Learn how error monitoring with Sentry closes the gap between the product team and your customers. With Sentry, you can focus on what you do best: building and scaling software that makes your users’ lives better.
React Native holds great promise for developers building cross-platform applications, and within a short span of time, it has passed the likes of Xamarin and Ionic.
React Native is a hybrid framework, which lets you build Android, and iOS application with easy code-sharing, and a faster shipping cycle.
However, often developers complain about performance issues in React Native, and it's the only bottleneck that's slowing down the adoption in startups.
React Native performance relies on the architecture, Native components, and libraries that you might be using in your application.
The more tabs, navigations, controls, and animations your application has, the slower it responds to user interactions.
Whenever you update your application, those changes get implemented from one version to another.
And, that consumes resources and keeps slowing down your performance.
To understand the performance bottlenecks, you first must understand the underlying architecture.
React Native Architecture
Native Part built on Java, Swift, or Objective-C.
If you look at the React Native GitHub page, there are tons of issues being reported by developers. Some issues are inherent, and others are implementation errors which can be easily resolved.
I analyzed 23 applications built on React Native and picked over 35 performance issues to write about. Here, I'm only discussing the major issues, so if you want to read more, you can follow the original source.
Moreover, I have also given insights on how to understand the root cause and resolve it to improve your application performance.
Memory leaks are pretty common issues for Android applications with a lot of unnecessary processes running in the background.
To fix memory leaks in Android applications, you can use scrolling lists such as FlatList, SectionList, or VirtualList instead of Listview.
Scrolling list also helps in smoothing the infinite scroll pagination, so if you're building an application with a pull to refresh feature, and large data points, then you should consider using it.
Large Application Size
To reduce the size, you have to optimize the resources, use ProGaurd, create different app sizes for different device architectures, and make sure to compress the graphics elements, i.e. images.
Moving Components From the Native Realm to the React Native Realm
However, you can follow these practices to reduce the load on the bridge and improve your app's performance:
Check the stability of open source libraries before you use them. Boilerplate codes in libraries often slow down the rendering performance.
Some components make heavy use of message queues while communicating with the Native side, so you should not pass them on the main thread.
In React Native, there are 4 navigation components that you can use in your application:
Navigator: Mainly used for prototyping and small applications, not good to deliver Native-like performance.
Navigator iOS: As the name suggests, it's only available for iOS.
Navigation Experiment: Was built to solve many pending GitHub issues, and still being used by many applications. However, Airbnb found it difficult to work with.
ReactNavigation: The performance is smooth and it is being used by 60% of the React Native applications.
If you ever wondered about the navigational difference between React Native and Native screens, here's a GIF that explains the difference visually:
App Launch time
Improving app launch time is an endless cycle of evaluating each and every component, looking for better performing libraries, reducing dependencies, etc. Often, an app's launch time is one of the biggest factor contributing to user churn.
To improve the launch time of a React Native application, you have to take care of the
Object.Finalize element which often slows down the app performance for users.
Even minor use of finalizers can lead to out-of-memory errors in your app, even though there is significant memory available.
Finalizers run on a single thread. If there are 1000 finalizers waiting to be run, you can imagine the time it would take to execute them all. This creates huge dependencies on the application before the launch.
Some React Native applications crash on changing the screen orientation from portrait to landscape. This might be a deal breaker for many users, especially in gaming or video applications.
Initially, developers were relying on react-native-orientation as one of the solutions to this challenge. But, we found out that react-native-navigation isn't able to determine the orientation lock on iOS devices.
More success with device orientation changes can be achieved by listening to the app's root view.
When React Native is rendering one component, other components have to wait till the first one is rendered.
Twitch had to move away from React Native because they couldn't implement a live chat feature along with a live video feed.
As we wrote before, a big part of software engineering is optimizing for performance.
Infinite scrolling's default implementation in React Native is often the biggest performance bottleneck for newsfeed type applications, where they have to process large data sets.
There are two ways to which you can implement infinite scroll:
- ScrollView: It renders all list/feed elements at once.
- ListView: Brings in additional rendering options (re-loading elements pre-defined).
- FlatList: For React Native versions > 0.43.
Image Caching in React Native
Image caching is important for loading images faster. As of now, React Native only provides image caching support on iOS.
For Android, there are a few npm libraries available, which does solve the image caching issue; yet even these don't offer the best performance.
A few challenges that we encountered are:
- Cache miss: Whenever an app's page is refreshed, often these libraries fail to fetch the previously loaded images.
Image Optimization in React Native
When you play around in React Native, it is very important to use responsive images. Otherwise, you may find that your app delivers sub-par performance and multiple error messages.
To optimize images in your React Native application, follow these best practices:
Use smaller sized images.
Use PNG as opposed to JPG.
Convert your images to WebP format.
WebP images can speed up your image loading time to 28%.
Maps in React Native
If you're working with a map feature, you will find that the dragging and navigation are pretty slow in React Native.
While integrating the map library in your React Native application, make sure to remove the console.log, so it doesn't store any data in the Xcode, and disable the auto-update of regions.
The goal here is to reduce the load on the JS thread, which improves the interactions with the map.
API JSON Data Optimization in React Native
Mobile applications always need to load resources from a remote URL or service, and, to perform such actions, developers make fetch requests to pull data from that server.
The fetched data from public and private APIs returns in a JSON form that has complex nested objects.
Frozen UI in React Native
Frozen UI occurs when there is a long operation running on the main thread, and the main thread blocks the UI thread from rendering. This situation gets even worse while rendering custom animations, large files, raw JSON data, or lots of map data.
To avoid this issue, don't use Object Finalizers, and make sure to not run heavy objects on the main thread.
React Native is a complex platform in terms of its architecture and its different components, libraries, and Native modules.
But, ever since its inception, organizations like Facebook, Airbnb, Instagram, Skype, and Tesla have trusted React Native to build their applications, which are being used by millions.
That commitment shows that React Native does have the potential to be the preferred choice for building high performing applications.
We have put together all major performance issues, along with countermeasures to improve your app's performance. Feel free to share your thoughts!
Published at DZone with permission of Purvak Pathak . See the original article here.
Opinions expressed by DZone contributors are their own.