React Native application are really slow most of the times. Large sets of the list, images, assets, API responses and multiple rendering, profiling, memorization, lazy-loading, I was thrown this many terms during the process of improving our application performance.
Understanding in-depth why the application is slow is not a cakewalk neither you can easily trace back the reasons why and which module is creating performance issue.
Measuring Performance?
The best way to measure React Native application performance by understanding the JS threads and their frames per second using Perf monitor. React Native depends on a native bridge to talk the native layer of android and ios software. Every single conversation between JS bridge and native software is considered as a single frame.
Any kind of user activity such as touched events and API responses and rendering of basic components in UI directly affects the frame rates and JS threads. So more time your API response will take more the JS thread will be blocked and more frames will be dropped hence the user will feel slowness or lag in the application.
Any response of API or component rendering is more than 100ms will decrease the frame rates by 12. so you have to beware of which particular API should call at what particular time and place within the react applications.
A lot of developers still believe that functional components are slower than class components so they tend to shift and make this transition in the entire application. Well, this is just a myth no such researched or solid reason is available to endorse this assumption it's just predictions.
Instead here are the reasons why your React Native application is slow.
1. Reduce Re-rendering
This case major issue in declining the frame rates. Most of the time updating a global context will re-render the deepest descendant using this context.
All consumers that are descendants of a Provider will re-render whenever the Provider's value prop changes.
This line is mentioned inside React-docs. Even though the child A component of the parent component is not updating any of its state or props it will get re-render if any of the components in the tree will update the context API.
You can calculate the no of rendering using profiling. by simply attaching the onRender callback function to major components you can check the renders count of each of those components.
2. Use Memoization
To avoid re-rendering is to memorize the component. Memoization basically caches the data and re-renders only when his state or props will change. Memoization helps the component to not re-render even if its nearby parent component props or state changes.
Using useMemo and useCallback hooks you can memoize the components.
3. Use Pure Components
Any component which will be static such as images, title, the heading should be treated as a Pure component. Try to make those components a Pure Component and you are good to avoid multiple rendering.
4. No Lazy Loading & Pagination
Always prefer to add pagination and lazy loading if you dealing with large sets of data and assets. Lazy loading helps to render only the components which are in view whereas pagination helps to fetch only the required amounts of data. Both the processes boost the performance.
5. Stop Overfetching data
If you dealing with real-time graphs, for example, stock markets you tend to fetch un-required data on the Frontend side. Over fetching the unnecessary data will increase the API response time and ultimately decrease the frame rates which again cause performance issues. Fetching only the required data will again boost the performance.
The one way of doing this in Frontend is to use GraphQL wrapper over REST API. This wrapper called REST API from GraphQL clients which helps API to return only the required data.
Calling REST API inside GraphQL queries
6. Use Flatlist over ScrollView
I have already covered an entire story on why Flatlist is better the ScrollView component in React Native. Flatlist provides lazy-loading, pagination and you using simple tricks like useMemo and Pure components inside flatlist you will able to avoid re-rendering also. These small changes boost the performance a lot.
Summary
-
Avoid re-rendering
-
Use Memoization & Pure components to avoid an unnecessary rendering
-
Add lazy-loading and pagination to boost the performance.
-
Implement GraphQL over REST API in Frontend to avoid an over fetching of data.
-
Use Flatlist over ScrollView component
Conclusion
I hope this story will be helpful because it took me almost a month to research and learn why my React Native application is slow. For more such stories please follow me. Until, next time, Have a good day, People.
Further reading: Memoization Demystified in 7 Minutes.