My team has been using React Native for about 2 years now. I’d like to share some lessons, resources, and best practices regarding React Native development. We are on the lookout for any more tips and guides to performance, UX, and other good practices, so please share other suggestions in the comments.
Our company, Vibemap, has a travel & lifestyle app for iOS & Android that is build with React Native and Mapbox. We knew we needed our app on Android from day one, and also need to provide a consumer level experience. React Native has made it possible to deliver an app on both platforms, but it’s also present us with a number of challenges.
One of the amazing benefits of React Native is being able to have a common code base that can be released to iOS and Android. The abstractions are not always perfect and we have found that in some scenarios who still need to write native, platform-specific modules for iOS and Android, and that means you might need to write some Swift, Objective C, or Java. As our project grew in complexity the build process also wasn’t seamless, especially the Gradle steps on Android.
It’s not just code sharing between iOS and Android that has helped us: since React Native is Javascript and React, we’ve been able to share most of our business logic and helper functions between our website and mobile app. In theory, you can even compile React Native components for web, but that introduced some overhead in terms of webpack bundle size and complexity. Webpack is a whole other story.
We also have a design system of colors, typography, layout rules, and component styles. Use design tokens and styled components, we’ve been able to reuse most but not all of our styles between web and mobile.
Here are the top ten lessons and best practices that have helped our team in our journey with React Native, and a few of the articles that have helped us:
- Optimize React Native Performance in 2021
- How to improve the performance of a React Native app
- 7 best practices that will increase React Native performance
1. Keep components small and avoid excessive renders
Keeping your project in a consistent structure of screens, high-order components, and UI components help keep you organized and productive and also makes it easier to employ code splitting, lazy, loading and other performance techniques. The React memo and useMemo APIs are two distinct tools that help to prevent re-rendering.
2. Enable Hermes and Keep React Native Up-To-Date
Hermes has given our app a dramatic performance improvements on both iOS and Android.
“Hermes helps reduce the download size of the APK, the memory footprint and consumption, and the time needed for the app to become interactive (TTI - Time to Interact).” – Codemagic
Getting the packaging of Javascript into bytecode on Android was a little mystifying, but we finally got it all working.
3. Use a UI library (with discretion)
There are many good out-of-the box components in React Native. That said, we’ve found that there some excellent UI library that provide a UX that rivals the native experience. We’ve tried to keep the experience consistent with iOS and Android guidelines. The React Native Paper library provides us with a nice selection of basic components and also Material Design components.
4. Use a Design System
Related to the UI library suggestion above, using a design system of reusable components has allowed us to keep the app experience consistent, and invest our effort into making cards, list, buttons, and other elements fast and responsive.
5. Use Flat List
Optimize list and make sure they have a key attribute, which reduce re-renders if the components data doesn’t change. For long list, use instead of :
“it’s advisable to choose FlatList over ScrollView to render all countable items with attributes of lazy loading that helps in improving the app’s performance.“ - Omji Mehrota
6. Clean up console statements and environment variable
Any console.log statements will add overhead to the Javascript thread. We also discovered from a friendly user’s security audit that by default React Native was storing some of our environment and config variables into an insecure place in the app bundle.
7. Use Firebase Crashalytics & Performance Monitoring
Another tool that’s been super helpful to our efforts is Firebase and their crashalytics tool. iOS and Android will also report crashed for React Native, but it can be difficult to diagnose the root cause. We found the stack traces in Firebase to be more informative. Plus you can report on all other app analytics and filters to specific devices that are exhibiting issue.
8. Server Response & Payload Size
One area where are team is still working diligently, is to speed up APIs and other data served to the mobile client. Our app loads data from a few different APIs, and we found that loading data for lists and maps was a major bottleneck. Similarly, images should be compressed and served in next-gen formats like Wepb.
9. Enable Ram Format
“Using the RAM format on iOS will create a single indexed file that React Native will load one module at a time.“ – Codemagic guide. Note that if you enable Hermes, this optimization is already implemented.
10. Reduce App Bundle Size
It probably can go without saying that you should remove any unused libraries and components. That said, as a project grows and changes, existing modules can be left in your package.json. So it’s a good practice to regularly update to newer versions and check their impact on your overall app size. We greatly reduced the size of our app by replace moment.js with day.js and used native Javascript methods in favor of LoDash.
Thanks for reading! Please send other suggestions and I’ll keep this article up-to-date. @stevepepple on Twitter and my personal blog.
Top comments (0)