Optimizing a React App

Harshit Bansal's photo
·

4 min read

Optimizing a React App

Before we start,

What is Single Responsibility Principle ?

It is an important principle in Computer Science Engineering. It means if you have a function or a class or any single identity of your code then it should have just a single responsibility. It is a good way to write code in modular fashion which makes it more reusable, maintainable and testable.

Need of Optimization

When we make our React app, we have several components in one React app (thousands of components in large scale apps), in that case having a different JavaScript file for each component would be a bad idea as we would not want our browser to keep sending network calls to load thousands of components, but with the help of bundlers, all the components are bundled in a single JavaScript file which is also not a good way as the size of the file might become big due to which browser can take time to load it which might slow down our app.

To solve these problems we break down our apps into several bundles or chunks of small sizes and they are loaded when they are to be used.

This process has several names like Chunking, Dynamic Bundling, Lazy Loading, Code Splitting, OnDemand Loading.

Dynamic Bundling

Dynamic Bundling is a technique used in web development to optimize the loading time and performance of web applications by breaking the application’s code into smaller chunks or bundles. These smaller bundles are then loaded only when they are needed, rather than all at once during the initial page load. This allows developers to serve only the necessary code for a specific part of the application, reducing the amount of unused code and improving performance, especially for large applications.

How it works ?

  1. Code Splitting: Dynamic bundling typically involves code splitting, where the application code is divided into smaller files (bundles). These bundles are loaded dynamically based on user interaction or route navigation.

  2. On-Demand Loading: When the user navigates to a specific route or triggers an action (like clicking a button), the browser loads the corresponding bundle only when required.

Libraries/Tools for Dynamic Bundling

  • Webpack: One of the most popular tools for bundling in modern web development. Webpack supports dynamic imports which can be used for code splitting.

  • React: React’s React.lazy and Suspense work together to enable dynamic bundling, particularly for route-based code splitting, so components are only loaded when they are rendered.

  • Parcel: A zero-configuration web application bundler that also supports automatic dynamic bundling.


Dynamic Bundling in React

In React, dynamic bundling can be easily achieved using lazy and Suspense. These two features allow React to lazy load components, meaning they are only loaded when the user needs them.

Lazy

The lazy function helps you dynamically import components only when they are needed. Instead of loading the entire application at once, it allows React to load the component only when it’s about to be rendered.

import {lazy} from 'react';

const Component = lazy(() => import('./Component'));

Here, lazy takes a function that imports a module. The component won’t be loaded until it is rendered in the DOM.

For example, if you have a large application and one of the components is only needed when a specific route is accessed (like a dashboard or user profile), you can use lazy to load that component only when the user navigates to that route.

Suspense

When a component is being lazy-loaded, there’s a delay as the browser fetches the JavaScript file. This can create a moment where your UI might appear incomplete, causing a poor user experience and also might throw an error. To handle this, Suspense is used to display a loading state while the lazy-loaded component is being fetched.

import {Suspense} from 'react';

<Suspense fallback={<div>Loading...</div>}>
  <Component />
</Suspense>

The fallback prop in Suspense specifies what should be displayed while the component is being loaded. In the example above, it shows a simple “Loading…” message.

So, Suspense is like a wrapper around the lazy-loaded component. It ensures that the user sees a fallback UI (like a spinner or loading text) until the component is fully loaded.

Best Practices for Dynamic Bundling in React

  • Route-Based Code Splitting: Lazy load components based on routes, so that only the components required for the current route are loaded.

  • Chunk Size: Try to keep the chunk sizes small to avoid long loading times for individual components.

  • User Interaction: If a component is shown after a user action (like opening a modal or clicking a button), lazy load it when the user interacts with the app.


This way, we can optimize our React app for faster and smoother UI which improves the user experience.