XenonStack Recommends

Enterprise Digital Platform

Code-Splitting in ReactJs with Its Best Practices

Navdeep Singh Gill | 28 October 2022

Code-Splitting in ReactJs with Its Best Practices

What is Code-Splitting?

Code splitting is the splitting of code into components or numerous bundles which can be loaded when there is a demand or in parallel. As an application grows, the complexity of it grows, too, and CSS bundles, especially as the number and size of libraries increases. It can be split into multiple smaller files to mitigate downloading all files. How to do this process will be explained in the below key points.

A tool that enables end users, administrators and organizations to gauge and evaluate the performance of a given system. Click to explore about, Performance Monitoring Tools and Management

Why do we need it?

Every day, users visit hundreds of websites and only stay a few times. According to Google’s survey, up to 53 percent of visits are abandoned if sites take longer than 2-3 seconds to load. Performance optimization is a major key point to achieve every developer deals with. The developer does their development local where they can see less or no performance issues, but after production, once we try to navigate the application, we immediately notice the render time is high, which explains that our application is slow.

While developing on a local server, all files are hosted from a local port: 3000. However, downloading large files becomes a major issue while the application goes live, So code-splitting plays a big and major role.

What are the best practices to implement Code-splitting?

The best practices for code splitting are defined below:

Component-based 

You might render different components inside your container component depending on the state, like whether or not a user is logged in. With the same Loadable component, we can accomplish this.

Consider this scenario, in which a component is only rendered into the view once the user clicks on it.

import React, { useState } from 'react';
import Loadable from 'react-loadable';
import Loader from 'components/Loader';

const SomeComponent = Loadable({
loader: () => import('components/SomeComponent'),
loading: Loading
});

const App = () => {
const [showComponent, setShowComponent] = useState(false);

return (
if (showComponent) {
return <SomeComponent />;
} else {
return (
<>
<h1>Hello word!</h1>
<button onClick={() => setShowComponent(true)}>Click me!</button>
</>
);
}
);
};

export default App;

It is the process of taking a large bundle of your application and dividing it into small parts components. If above we use another function to render, we can divide from the main app and import it as a component in the main bundle from where we can utilize its functionality.

Route-centric code splitting

The following are the steps for Route-centric code splitting

Dynamic Imports
This is a JavaScript feature that similarly imports our files to promise.

Before:

import Login from "Pages/Login.js";
import Home from "Pages/Home.js";
import About from "Pages/About.js";
import Contact from "Pages/Contact.js";
import Blog from "Pages/Blog.js";
import Shop from "Pages/Shop.js";

Static import is used in the code above to import our files. Webpack combines all the files when it encounters this syntax. We're doing this because we'd like to include them both statically.

After:

const module = await import('/modules/myCustomModule.js');

Dynamic imports are asynchronous, in contrast to synchronous static imports. We can now import our modules and files whenever we want. When webpack encounters this syntax, it begins code splitting our application right away.

React.lazy()

This is a component function that takes another function as an argument. This function does a dynamic import and returns a promise as a result. React handles this promise.lazy(), which expects a module to be returned containing a default export React component.

Before:

import Login from "Pages/Login.js";

After:

import React, {lazy} from "react";
const Login = lazy(()=> import("Pages/Login"));

The login page is now lazy-loaded, which means the Login.js chunk is only loaded when the page is shown.

A modern, statically typed, general-purpose, high-level programming language supporting object-oriented and functional programming. Click to explore about, Functional Programming in Scala

React.Suspense()

We can use React.Suspense() to conditionally halt a component's rendering until it has loaded. It has a fallback prop that takes a React element as a parameter. A JSX snippet or a whole component can be used as a React element.

A user may see a blank screen while the app loads the module on a page that supports dynamic imports. Because dynamic imports are asynchronous, a user may receive an error.

If the user has a slow internet connection, the chances of this happening rise.This problem is solved by combining React.lazy() and React.suspense(). WhileReact.Suspense suspends a component's rendering until all of its dependencies are lazy-loaded. It also serves as a fallback UI by displaying the React element supplied to the fallback props.

Consider the code below:

import React, { lazy, Suspense } from 'react';

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

const Home = () => {
return (
<div>
<Suspense fallback={<div>Page is Loading...</div>}>
<section>
<Font />
<Service />
</section>
</Suspense>
</div>
);
}

The font and service components are lazy-loaded here. These are the home component's dependencies. It is required that they display the entire homepage.
We utilize the suspense component to prevent a user from seeing an error or a blank page when they visit the homepage by suspending the rendering of the home component until dependencies are lazy-loaded.

The user is now presented with the following fallback UI while a component is being lazy-loaded:

<div>Page is Loading...</div>

React-router

Route-level code-splitting is supported out of the box by the react-router-dom package. It enables us to download portions on a route-by-route basis. As a result, we'll code split at the route level, which will be quite useful.

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const Shop = lazy(() => import('./routes/Shop'));

const App = () => {
return (
<Router>
<Suspense fallback={<div>Page is Loading...</div>}>
<Switch>
<Route exact path="/" component={Shop} />
<Route path="/shop" component={Shop} />
</Switch>
</Suspense>
</Router>
)
}

Here, we set our routes using the react-router-dom library, and the shop and home components are loaded as lazy-loaded. Here suspense covered all the routes, ensuring that a fallback UI is rendered while the requested components are lazy-loaded.

A way of writing applications using only pure functions and immutable values. Click to explore about, Functional Programming

Conclusion

Lazy and Suspense to create a better React app. React itself comes with an optimized solution while we use create-react-app. For further enhancement, code-splitting needs to reduce render time, which states in dynamic imports, react.