Optimizing React Native Performance: Realtime data with Websockets (2023)

Optimizing React Native Performance: Realtime data with Websockets (1)

React Native is an extremely powerful framework for developing mobile applications for both iOS and Android platforms. With its ability to create cross-platform applications using a single codebase, it has become the go-to choice for many developers. However, there are still some challenges that developers face while using React Native as part of highly complex, scalable, low latency and performant distributed systems. In this post, we’ll break down a problem statement that often comes up while developing mobile apps using React Native and how to go about solving it.

The Problem: Many mobile apps nowadays need to have real-time updates, often coming straight from the backend server. For example: showing live cricket/football match updates on an OTT app, online multiplayer games, or listening to a live podcast.

Optimizing React Native Performance: Realtime data with Websockets (2)

For the purpose of this discussion, we will consider the case for showing live price action for a stock, index, cryptocurrency, unit, etc to the user on a second-to-second basis. The key challenge here is to ensure that the application remains highly responsive while continuously handling updates coming from the server. This is considered to be a non-trivial problem since React Native is a JavaScript-based framework, and JavaScript is, by nature, single-threaded. Blocking the main thread with network requests or any long-running operation would obviously result in a non-responsive application.

Optimizing React Native Performance: Realtime data with Websockets (3)

The Solution: To solve this type of use case, we can use a combination of various libraries and technologies that tie well into addressing this problem. The key to choosing an optimal approach is to consider what works best for the problem at hand. It’s important to be mindful of any trade-off being made, and other constraints like budget, deadlines and current skillset. Here are some steps I would recommend to reach an optimal solution:

Step 1 - Using WebSockets: WebSockets are a great communication protocol to establish a real-time connection between the application and the server. Using sockets allow the server to push updates to the client without the client having to make continuous HTTP requests, also known as the Publish Subscriber Pattern (PubSub for short). This helps to reduce the load on the network and allows the mobile app to continuously receive updates in real-time. Let’s quickly revisit a short primer on how to implement Websockets in your React Native app:

First, we need to install the ws package which provides a WebSocket implementation for Node.js:

$ npm install ws --save

Then we import the Websocket class to create a new socket to listen on:

import { WebSocket } from 'react-native';

const ws = new WebSocket('wss://sample-currency-api.com/socket');

We can then use the onopen, onmessage, and onclose callbacks to handle WebSocket events:

ws.onopen = () => {
console.log('WebSocket connected');
};

ws.onmessage = (event) => {
console.log('Received message:', event.data);
//
// parse the currency information here from the 'event' data packet
//
};

(Video) Optimizing Rendering Performance in React

ws.onclose = () => {
console.log('WebSocket closed');
};

Also, in case we want to send data over the WebSocket to the backend, we can use the send method:

ws.send('Hello, server!');

And that’s it! With WebSockets now integrated, we can establish a real-time connection between our React Native app and the backend server, allowing us to receive updates in real-time without needing to make continuous HTTP requests.

Step 2 - Using Background Threads: To prevent the main thread from being blocked, I recommend using background threads to handle the network requests. We can create a separate thread to listen to updates from the server. This ensures that the main thread remains free to handle user interactions.

Optimizing React Native Performance: Realtime data with Websockets (4)

Step 3 - Use Throttling: To avoid overwhelming the application with a large number of events/notifications, we must implement some form of throttling. Throttling is a mechanism that allows us to control the rate at which updates are received from the backend or even the underlying system, saving resources that can be reallocated for smoother UI. When we throttle a function, it will only be invoked once in a given period, no matter how many times its corresponding event listener is triggered.

I suggest using the Lodash library to implement throttling. We can install just lodash.throttle by running the following command on our terminal:

$ npm install lodash.throttle

Next, we’ll use the following line of code to import it:

import throttle from 'lodash.throttle'

After that, we call the throttle method and supply the function we want to debounce as its first argument, the wait time (in milliseconds) as the second argument, and an optional config object as the third argument.

Here’s an example of this approach in a hypothetical component to display realtime price information for a given stock, called StockPrice component:

import React, { useEffect, useState } from 'react';
import { Text, View } from 'react-native';
import _ from 'lodash';

const socket = new WebSocket('wss://sample-currency-api.com/socket');

const StockPrice = () => {
const [price, setPrice] = useState(0);

useEffect(() => {

// Here we pass the throttling function to the event listener
socket.onmessage('stockPrice', _.throttle(data => {

(Video) Don't Use Websockets (Until You Try This…)

// The state-mutating business logic goes inside the throttle function
setPrice(data.price);

}, 500)); // 500 ms wait time (at most) for setPrice calls

}, []);

return (
<View>
<Text>{`Stock Price: ${price}`}</Text>
</View>
);
};

export default StockPrice;

In this example, we import lodash.throttle as _ and use it to throttle the stock price data received from the socket.on event. The throttle function wraps the callback function that sets the price state variable, ensuring that it is called at most once every 1000ms (1 second), which helps to prevent an excessive amount of updates.

The useEffect hook is used to subscribe to the stockPrice event on the socket object, and the setPrice function is called within the throttled callback to update the price state variable with the latest stock price data.

Finally, the StockPrice component is rendered with the current stock price displayed in a Text component within a normal View. Here is a great stackblitz code sample that demonstrates throttling in React with Lodash.

Step 4 - Implementing Redux: To manage the application state, Redux is a great candidate. Redux is a predictable state management framework for JavaScript applications. It helps simplify the data flow between different components in the application. I also suggest Redux-Saga to handle the asynchronous operations.

Here’s a step by step installation guide with relevant code samples:

  1. Setting up the Redux Store:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const store = createStore(rootReducer, applyMiddleware(thunk));

export default store;

2. Creating the Actions:

export const updateStockPrices = (stockData) => {
return {
type: 'UPDATE_STOCK_PRICES',
payload: stockData,
};
};

3. Defining the Reducers:

const initialState = {
stockData: [],
};

const stockReducer = (state = initialState, action) => {
switch (action.type) {
case 'UPDATE_STOCK_PRICES':
return {
...state,
stockData: action.payload,
};
default:
return state;
}
};

(Video) Real Time Data Sending with SocketIO

export default stockReducer;

4. Creating Async Action Creators

import { updateStockPrices } from './actions';
import _ from 'lodash';

export const fetchStockPrices = () => {
return (dispatch) => {
const socket = new WebSocket('wss://sample-currency-api.com/socket');

socket.onmessage('stock_price', _.throttle(event => {

const stockData = JSON.parse(event.data);
dispatch(updateStockPrices(stockData));

}, 500));
};
};
};

5. Dispatching the Actions

import { fetchStockPrices } from './actions';

const App = () => {
const dispatch = useDispatch();

useEffect(() => {
dispatch(fetchStockPrices());
}, []);

return (
<View>
<Text>Stock Prices</Text>
{stockData.map((data) => (
<Text>{data.stock_ticker}: {data.price}</Text>
))}
</View>
);
};

These are just some sample snippets to give you an idea of how Redux can be used to manage and display stock price data coming from a WebSocket in a React Native app. Depending on your specific requirements, your implementation may differ.

Step 5 - Using Custom Animations: To create a more engaging user experience, we can try using custom animations to display the instant updates. Animations help to make the notifications more attention-grabbing and riveting, which in turn tend to increase user engagement and focus on this particular functionality.

Let’s see how we could achieve a simple slide up and down text animation to denote stock price going up or down as well as change the text color between red and green depending on the most recent price action:

import { useState, useEffect } from 'react';
import { View, Text, Animated, StyleSheet } from 'react-native';
import _ from 'lodash';

const StockTicker = () => {
const [price, setPrice] = useState(10);
const [prevPrice, setPrevPrice] = useState(5);
const animatedValue = new Animated.Value(0);

useEffect(() => {
const socket = new WebSocket('wss://sample-currency-api.com/socket');

(Video) How I scaled a website to 10 million users (web-servers & databases, high load, and performance)

socket.onmessage = ('stock_price', _.throttle(event => {

const stockData = JSON.parse(event.data);

dispatch(updateStockPrices(stockData));
const newPrice = stockData.price;

// Save previous price and update current price
setPrevPrice(price);
setPrice(newPrice);

Animated.timing(animatedValue, {
toValue: newPrice,
duration: 300,
useNativeDriver: true
}).start();

}, 500));

return () => {
socket.close();
};
});

// Calculate the percentage change between the previous and current price
const percentChange = ((price - prevPrice) / prevPrice) * 100;

// Determine the color based on the percentage change
const textColor = percentChange > 0 ? 'green' : 'red';

const animatedStyle = {
transform: [
{
translateY: animatedValue.interpolate({
inputRange: [0, 100],
outputRange: [0, -100],
extrapolate: 'clamp'
})
}
]
};

return (
<View style={styles.container}>
<Text>Stock Price:</Text>
<Animated.Text style={[
styles.priceText,
animatedStyle,
{ color: textColor }]}>
{price.toFixed(2)}
</Animated.Text>
</View>
);
};

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
priceText: {
fontSize: 24,
fontWeight: 'bold',
},
});

export default StockTicker;

Here’s a breakdown of what this code does:

  • First, we define a couple of useState hooks to keep track of the old and new stock prices. These values will be updated by the useEffect hook that handles receiving data from a web socket.
  • We create a new instance of Animated.Value called animatedValue. This is the value that will be animated over time.
  • We define a textColor variable based on the updated value of the stock price. If the price change is positive, the text’s color will be green, otherwise it will be red.
  • In the useEffect hook, we animate the animatedValue whenever the stockPrice changes. We use the Animated.timing method to animate the value from its current value to the new stockPrice value over a duration of 300 milliseconds.
  • We calculate the translateY value based on the animatedValue. The interpolate method maps input values to output values. In this case, we map the input range of -100 to 100 to the output range of 200 to -200. This means that as the animatedValue increases, the text will move up, and as it decreases, the text will move down.
  • Finally, we render the Animated.Text component with the translateY transform and the color style. As the animatedValue changes, the text will move up and down on the screen, and the color will change from red to green (or vice versa) depending on the direction of the change.

Want to view the code in a live coding environment? Follow this link to view the entire sample app in this awesome Expo online IDE. Cheers!

Optimizing React Native Performance: Realtime data with Websockets (5)
Optimizing React Native Performance: Realtime data with Websockets (6)

And there you have it! An optimized and robust implementation of a Stock price ticker UI to efficiently display realtime price information coming from external sources. With these steps, you can easily solve the problem of creating a highly responsive React Native mobile UI that can receive and display real-time updates from the server. The combination of WebSockets, background threads, data throttling, Redux stores, and custom animations can be leveraged to help to create a smooth and engaging user experience.

(Video) Why I Avoid Working With WebSockets in NextJS and tRPC

Want to turn your ambitious business idea into a beautiful mobile app without having to deal with complex technology teams in-house? Worry not! At Dev Mastery HQ, we help you bring your idea to life. You can reach out to us with your queries on our website or send them to the co-founder directly on LinkedIn, Github, StackOverflow, or via Mail. We’re more than happy to help you take your product to greater heights.

FAQs

How do you optimize the performance of React Native app? ›

Some best React Native app image practices include using PNG format instead of JPG format and smaller-resolution images. You may also utilize WEBP format for reducing the binary size of your images on iOS and Android by almost a third of the original size.

Can you use WebSockets in React Native? ›

React Native also supports WebSockets, a protocol which provides full-duplex communication channels over a single TCP connection.

What is the best WebSocket library for React Native? ›

A good library for providing robust WebSocket integrations in React is called react-use-websocket. This library provides a custom React hook for implementing WebSocket integrations and it has experimental support for SocketIO.

Are WebSockets obsolete? ›

Websockets are largely obsolete because nowadays, if you create a HTTP/2 fetch request, any existing keepalive connection to that server is used, so the overhead that pre-HTTP/2 XHR connections needed is lost and with it the advantage of Websockets.

What is the performance bottleneck in React Native? ›

The performance bottleneck in React Native app occurs when you're passing the components from one thread to other unnecessarily or more that the required. A major thumb rule to avoid any kind of performance related issue in React Native is to keep the passes over the bridge to a minimum.

What language works best with WebSockets? ›

A WebSocket server can be written in any server-side programming language that is capable of Berkeley sockets, such as C(++), Python, PHP, or server-side JavaScript.

Is there an alternative to WebSockets? ›

While WebSockets can be used for various applications, MQTT is explicitly designed for machine-to-machine communication, which is why it's considered an alternative under these use cases. MQTT provides features like low overhead, efficient message delivery, and support for offline operation.

What is faster than WebSockets? ›

WebRTC primarily works over UDP, while WebSocket is over TCP. This means that WebRTC offers slightly lower latency than WebSockets, as UDP is faster than TCP. However, the difference is negligible; plus, TCP is more reliable when it comes to packet delivery (in comparison, with UDP some packets may be lost).

Which is the best choice for real-time data WebSockets or rest API? ›

WebSocket approach is ideal for real-time scalable applications, whereas REST is better suited for the scenario with lots of getting requests. WebSocket is a stateful protocol, whereas REST is based on a stateless protocol, i.e. the client does not need to know about the server and the same hold true for the server.

What is the fastest WebSocket client library? ›

In this benchmark there is one clear winner: uWebSockets-library. uWebSockets, which is written in C/C++, was the fastest performing WebSocket server both when used with Node. js and Python. The speed is impressive but so is the resource usage.

What are the weaknesses of WebSocket? ›

Drawbacks or disadvantages of Websockets

Intermediary/Edge caching is not possible with websockets unlike HTTP. ➨To build even simple protocol of your own, one can not be able to use friendly HTTP statuses, body etc. ➨If application does not require a lot of dynamic interaction, HTTP is much simpler to implement.

What is the disadvantage of using WebSocket? ›

The biggest downside to using WebSocket is the weight of the protocol and the hardware requirements that it brings with it. WebSocket requires a TCP implementation, which may or may not be a problem, but it also requires an HTTP implementation for the initial connection setup.

What makes React Native slow? ›

Reasons for a Slow React Native App

An app with a complex UI with many nested components takes longer to render, leading to poor performance. Unnecessary re-renders cause the app to slow down. This can be caused by excessively using the setState method or not using the shouldComponentUpdate lifecycle method.

Is React Native fast enough? ›

React Native makes them faster to develop and as of now offer enough support and modules to build a stable application. Another advantage is that when your web app is built in React, it is also easier to build a React Native mobile app.

Which time picker is best React Native? ›

React Native DateTimePicker

This package has a descriptive README and is up to date with one of the newest React Native versions. This makes it one of the strongest candidates if you're looking for a date and time picker with a native feel for your app.

How do I reduce RAM usage in React Native? ›

Virtualized Lists: React Native provides a FlatList component that virtualizes long lists, meaning that it only renders the items that are currently visible on the screen. This can significantly reduce the memory usage of your app, especially if you are working with large lists of data.

What is lazy loading in React Native? ›

In simple terms, lazy loading is a design pattern. It allows you to load parts of your application on-demand to reduce the initial load time. For example, you can initially load the components and modules related to user login and registration. Then, you can load the rest of the components based on user navigation.

Are WebSockets bad for performance? ›

WebSockets are arguably better in real-time performance when it comes to web applications, so we've had our concerns about using HTTP in some parts of our architecture. Perhaps the better solution was to improve our tooling and code quality around WebSockets, and not turn away from it.

Why are WebSockets so slow? ›

The underlying websocket transport is TCP, and this topic of coordinating different rates of sending and receiving is called flow control (it is a feature of TCP layer), and this specific problem is known as "slow consumer" (and is common when sending out very high amounts of data over TCP, such as financial market ...

Why use REST instead of WebSocket? ›

WebSockets have a low overhead per message. They're ideal for use cases that require low-latency, high-frequency communication. REST APIs have a higher message overhead compared to WebSockets. They're best suited for use cases where you want to create, retrieve, delete, or update resources.

What port is best for WebSockets? ›

WebSocket connections generally work even if a proxy or firewall is in place. This is because they use ports 80 and 443 which are also used by HTTP connections. In some situations WebSocket connections are blocked over port 80. In this case a secure SSL connection using WSS over port 443 should successfully connect.

How much faster are WebSockets? ›

As is clear from the table, for our use case Websocket is expected to be about 5-7 times faster than plain HTTP. 3. Security: From security perspective, both HTTP (via HTTPS) and Websockets via (WSS) provide the TLS layer so there is not much to choose from.

Do WebSockets use a lot of data? ›

Data consumption is depending on the data you are transmitting, just for the connection it is not very much.

Why WebSockets are not scalable? ›

Before: Each WebSocket server needs to process every state update, filter messages addressed to connected clients and forward it along. Thus the scalability of the system is limited by the maximum throughput of a single server for processing state updates.

Which is better MQTT or WebSocket? ›

MQTT is suitable for low-powered devices with limited CPU and memory, and unreliable, low-bandwidth networks. It's the go-to protocol for IoT use cases. WebSockets are suitable for web apps and devices unrestricted (or less restricted) by low bandwidth.

Are server sent events better than WebSockets? ›

Server-Sent Events is a good alternative to WebSockets for simple realtime use cases that only require one-way communication (from server to client). Examples include read-only realtime apps like stock tickers, or news updates.

How many WebSockets is too many? ›

WebSocket libraries and web browsers enforce different limits on the number of WebSocket connections. For example, at the time of writing (14th of April 2023), Chrome allows up to 256 concurrent connections per client by default, while Firefox can handle 200 connections per client by default.

Is WebSockets real-time? ›

What is WebSocket? In a nutshell, WebSocket is a realtime web technology that enables bidirectional, full-duplex communication between client and server over a persistent connection.

Are WebSockets fast enough for games? ›

Yes, they are.

Is WebSocket resource heavy? ›

It will be resource-heavy for the client to request 100s of rates every second using REST API, whereas the Websocket client can receive 100s of rates a second without being too resource-intensive. See C# Websocket Tutorial.

When would you choose WebSockets over HTTP for APIs? ›

Also, APIs can be used with both web and mobile applications and service integrations with ease. But, if your web application requires real-time communication with the backend, you should choose WebSockets. It allows you to establish a 2-way communication channel between your browser and the backend.

Do WebSockets allow full-duplex communication? ›

WebSocket is a standard protocol that enables a web browser or client application, and a web server application to use a full-duplex connection to communicate.

Is Socket.io faster than WebSocket? ›

On the other hand, for more complex use cases, such as a chat app, Socket.IO is a superior alternative, as it allows you to move faster than plain WebSockets.

How many WebSockets can run concurrently? ›

Your VMs can definitely support 50 concurrent websocket connections on those small VMs, especially if they're somewhat idle. You can potentially handle 1000 concurrent connections on those small VMs.

Would WebSockets be able to handle 1000000 concurrent connections? ›

With at least 30 GiB RAM you can handle 1 million concurrent sockets. The CPU needed depends on the data throughput you need.

How long can a WebSocket last? ›

In general, WebSocket connections can stay open indefinitely as long as both the client and server remain connected and the network is stable.

Can WebSockets be hijacked? ›

Cross-Site WebSocket Hijacking (CSWSH) is a type of security vulnerability that occurs when a WebSocket connection is established between a user's browser and a remote server.

Are WebSockets a security risk? ›

WebSockets let anyone tunnel an arbitrary TCP service. An example is tunneling a database connection directly through and reaching the browser. In the case of a Cross-Site Scripting attack it evolves and ends up becoming a complete security breach.

Can a WebSocket handle multiple connections? ›

A server can open WebSocket connections with multiple clients—even multiple connections with the same client. It can then message one, some, or all of these clients. Practically, this means multiple people can connect to our chat app, and we can message some of them at a time.

Are WebSockets more secure than rest? ›

Whether you chose REST or WebSocket, one thing is certain your application will be able to communicate properly with other apps/software. You need to pick one based on your communication requirements and expectations. REST is far advanced and secured while WebSocket depends on lower-level components.

How much data can WebSocket send? ›

WebSockets allows you to transfer as much data as you'd like without incurring the overhead associated with traditional HTTP requests. Data that is transferred through a WebSocket is referred to as messages. These messages consist of one or more frames that contain the data you're sending (the payload).

Why is my React Native app so slow? ›

Reasons for a Slow React Native App

An app with a complex UI with many nested components takes longer to render, leading to poor performance. Unnecessary re-renders cause the app to slow down. This can be caused by excessively using the setState method or not using the shouldComponentUpdate lifecycle method.

How do I reduce React Native build time? ›

Build only one ABI during development (Android-only)

This should reduce your native build time by a ~75% factor. If you're using the React Native CLI, you can add the --active-arch-only flag to the run-android command.

How do I make my React app scalable? ›

Components are the building blocks of React applications, and they make it easy to create reusable and composable UI elements. To ensure scalability, it's important to design components with reusability in mind. This means that components should be focused, small, and independent.

How do I enable fast refresh in React Native? ›

Fast Refresh is a React Native feature that allows you to get near-instant feedback for changes in your React components. Fast Refresh is enabled by default, and you can toggle "Enable Fast Refresh" in the React Native developer menu. With Fast Refresh enabled, most edits should be visible within a second or two.

Does React Native have lazy loading? ›

React Native does not support code splitting and lazy loading out of the box, unlike some web frameworks like React or Vue. However, there are some libraries and tools that can help you implement these techniques in your React Native app.

What is the difference between hot reloading and live reloading in React Native? ›

The difference between the two is, Live Reloading is gonna reload your entire application. It's just gonna be like, okay, the file changed, reload the entire app. Hot Reloading is not gonna reload your entire application. It's just going to patch the code that was changed and keep the state in your app.

What is the best way to upgrade React Native? ›

Because typical React Native projects are essentially made up of an Android project, an iOS project, and a JavaScript project, upgrading can be rather tricky. There's currently two ways for upgrading your React Native project: by using React Native CLI or manually with Upgrade Helper.

Videos

1. Can NODE.JS Server Handle 1M Concurrent Requests? | Real-World App Benchmarking on Dedicated VPS
(CoderOne)
2. Why WebSockets Are NOT Scalable | WebSockets Explained
(codedamn)
3. Build A Realtime Chat App In ReactJS and NodeJS | Socket.io Tutorial
(PedroTech)
4. 4 Runtime Performance Optimizations
(Angular)
5. Build a Video Streaming Service like YouTube, Netflix using AWS S3, CloudFront and React
(Felix Yu)
6. Measuring performance of React Native apps in production | React Native London | April 2022
(Pusher)

References

Top Articles
Latest Posts
Article information

Author: Greg O'Connell

Last Updated: 09/12/2023

Views: 6045

Rating: 4.1 / 5 (42 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Greg O'Connell

Birthday: 1992-01-10

Address: Suite 517 2436 Jefferey Pass, Shanitaside, UT 27519

Phone: +2614651609714

Job: Education Developer

Hobby: Cooking, Gambling, Pottery, Shooting, Baseball, Singing, Snowboarding

Introduction: My name is Greg O'Connell, I am a delightful, colorful, talented, kind, lively, modern, tender person who loves writing and wants to share my knowledge and understanding with you.