Lazy Loading and Code Splitting in React.js with TypeScript: Boosting Performance and User Experience
Introduction: Lazy loading and code splitting are powerful techniques that can significantly improve the performance and user experience of React.js applications. In this step-by-step guide, we will explore how to implement lazy loading and code splitting in a React.js application using TypeScript. By the end, you will have a clear understanding of how to optimize your application's bundle size and load components on-demand.
Step 1: Set Up a React.js Project with TypeScript Create a new React.js project with TypeScript support using Create React App:
npx create-react-app lazy-loading-app --template typescript
cd lazy-loading-app
and open it your favourite code editor.
Step 2: Create a Component to Lazy Load Create a new component that you want to lazy load in your application. Let's create a LazyComponent.tsx
file:
import React, { useState, useEffect } from "react";
interface Item {
id: number;
title: string;
price: number;
}
const LazyComponent: React.FC = () => {
const [error, setError] = useState<Error | null>(null);
const [isLoaded, setIsLoaded] = useState(false);
const [items, setItems] = useState<Item[]>([]);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((res) => res.json())
.then(
(result) => {
setIsLoaded(true);
setItems(result);
},
(error) => {
setIsLoaded(true);
setError(error);
}
);
}, []);
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
} else {
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
}
};
export default LazyComponent;
Step 3: Implement Lazy Loading with React.lazy In your main app component, import the React and React.lazy modules, and use the React.lazy function to dynamically import the lazy-loaded component. Wrap it with the Suspense component to handle the loading state. Update App.tsx
as follows:
import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./LazyComponent'));
const App: React.FC = () => {
return (
<div>
<h1>Welcome to My App</h1>
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
</div>
);
};
export default App;
Step 4: Configure Code Splitting with Webpack By default, Create React App handles code splitting for you. You don't need to modify the Webpack configuration manually. However, you can customize the output filenames and chunk names if needed.
Step 5: Test the Lazy Loading and Code Splitting Start the development server and test the application:
npm start
Open your browser and navigate to http://localhost:3000
. You should see the "Loading..." message initially, and after a moment, the lazy-loaded component will be displayed.
Step 6: Handle Loading and Error States To improve the user experience during the loading phase, you can provide fallback content or loading spinners in the Suspense component. Additionally, you can implement error boundaries to catch any errors that occur during the lazy loading process. Update App.tsx
as follows:
import React, { Suspense } from 'react';
const LazyComponent = React.lazy(() => import('./LazyComponent'));
const App: React.FC = () => {
return (
<div>
<h1>Welcome to My App</h1>
<Suspense fallback={<div>Loading...</div>} onError={<div>Error!</div>}>
<LazyComponent />
</Suspense>
</div>
);
};
export default App;
Step 7: Optional - Route-Based Code Splitting If you're using a routing library like React Router, you can implement route-based code splitting. Configure your routes to dynamically import and load the components only when the corresponding route is accessed.
Step 8: Profile and Optimize Performance Use performance profiling tools like React DevTools and Chrome DevTools to analyze the application's performance. Identify any performance bottlenecks, such as large initial bundles or slow-loading components, and optimize accordingly.