Remove all unused resources and library dependencies. Optimize all resource files (e.g. splash screens and static images). Enable Proguard to reduce the size of the APK. It strips parts of the React Native Java bytecode (and its dependencies) that your app is not using. To enable Proguard, edit android/app/build.gradle:
def enableProguardInReleaseBuilds = true
Provide key property when rendering list items in order to help React to perform change detection more efficiently. Otherwise, the JS thread will send unnecessary data to shadow thread through RN bridge which requires serialization/deserialization and rerendering UI components in the main thread.
Stop React reconciliation phase and prevent component from rendering if certain props are not changed.
Combine multiple requests for cached data on the disc (e.g. AsyncStorage) into one. Instead of accessing multiple keys from AsyncStorage you can grab whole object at once. Startup phase will be faster if those requests are batched.
When scrolling down a long list, the memory footprint increases linearly and eventually exhausts all available memory. The main advantage of FlatList is that is has nearly constant memory usage for any number of rows.
When using Javascript navigation all transitions and animations are being executed in Javascript thread. If there’s a content which needs to be rendered on the page (long lists, maps, animations...), while transitions is executing, the application will not be able to respond and frames will be lost, because Javascript is single threaded. Currently available native solutions are React Native Navigation by Wix and Native Navigation by AirBnb. React Navigation is the official solution from React team based on Javascript.
Native driver transfers the animation execution to main thread, instead of Javascript thread. In that case Javascript operations can be performed independently. If your user experience is suffering way more than expected, then you should better stick with Layout Animation. Layout Animation is used e.g., when animating in a modal (sliding down from top and fading in a translucent overlay) while doing something else at the same time (while initializing and perhaps receiving responses for several network requests, rendering the contents of the modal, and updating the view where the modal was opened from)
This process consumes a lot of memory because every time a user adjust the width or height of an image it is re-cropped and scaled from the original image size. When resizing the image (tap to zoom in etc.) use transform: [{scale}] style property to animate the size or, even more efficient, implement a custom FadeInImage component to display a tiny shade
It can speed out your image loading time to 28%.
In order to display an image shell while image is not yet loaded from the server use defaultSource property as image placeholders or react-native-image-placeholder npm package.
Display small thumbnail first (easy to fetch from the server) and replace it with real image once the image is being loaded. Code to achieve this: ProgressiveImage.js
If there’s a problem with memory leak because of images try to reduce the image size or use JPEG instead of PNG because downsampling is disabled for PNGs in React Native, since it is still experimental.
Cleanup all console.log() statements using Babel plugin.
When launching React Native app it takes time to load a JavaScript Context and do the initial rendering. It results in a white screen splash. Use initial loading view at startup to avoid this: React Native Initial Loading View.
If your application uses a lot of memory it could lead to memory leak. Possible solution is to set
<application android:largeHeap="true"
in “android/app/src/main/AndroidManifest.xml” file.