Performance and Code Splitting with Rspack
Performance can be a big deal. For every optimization there is a sacrifice being made. As applications grow in complexity, the need for efficient resource loading becomes increasingly vital. Enter code splitting - a technique that may not be so new to you but it's revolutionized content delivery on the web. At the forefront of this revolution is Rspack, my web bundler of choice that excels at optimizing and packaging web applications.
What is Code Splitting?
Code splitting is the process of breaking down a JavaScript bundle into smaller chunks that can be loaded on demand. This is crucial for improving load times, particularly in large-scale applications. Instead of downloading the entire JavaScript bundle upfront, users only download the necessary code for their current page or feature, significantly reducing the initial load time.
In the context of Rspack, code splitting can be implemented using dynamic imports. Dynamic imports enable you to load JavaScript modules dynamically at runtime, rather than including them in the main bundle.
Code Splitting with Rspack
Efficient Performance: Rspack is a highly performant tool. Utilizing concepts like Code Splitting and Tree Shaking, it ensures that your web application loads faster and only what's needed. Supporting HTTP/2, it has the ability to split your code into many pieces that can be loaded in parallel, drastically improving loading times.
Loaders and Plugins: Rspack boasts of a variety of loaders and plugins to make the development process smooth. Loaders preprocess files, allowing you to bundle any static resource, while plugins provide a wide range of solutions such as bundle optimization, environment variable injection, and HTML generation.
Import Magic Comments: Rspack takes advantage of Webpack’s import syntax to provide the developer with succinct control over the chunk names, which can be useful in debugging and provides a way to control caching via customized chunk names.
Webpack Compatibility: Rspack aims to maintain a high level of compatibility with Webpack's plugin and loader ecosystem. Developers familiar with Webpack's configuration can easily set up and configure Rspack. Many of Webpack’s features, such as code splitting, dynamic imports, module federation, hot module replacement, among others, are supported by Rspack as well.
Implementing Code Splitting in Rspack
There are three primary methods for code splitting in Rspack:
- Entry Points: Manually split code using the entry configuration.
- SplitChunksPlugin: Use this plugin to deduplicate and split chunks, extracting shared modules into a new chunk.
-
Dynamic Imports: Using the
import()
syntax for dynamic imports to split code within modules.
Each method has its own configuration approach and use case, providing flexibility and control over how your assets are generated and managed. In this blog post, we are going to use the dynamic imports method.
For detailed code examples and further explanation, you can refer to Rspack's code splitting official documentation.
Setting Up Rspack/Rsbuild
Prerequisites
- Node.Js
- JavaScript/Framework of choice knowledge
Before diving into code splitting techniques, ensure you have Rspack installed. Rspack supports frameworks like Svelte, React, Vue, SolidJS, NestJS, and Modern.JS:
npm create rsbuild@latest
When you run this command, let it load and choose a framework you want to work with. For this example, I'll be using React. Rspack and React work well together and have they both have some built-in features we'll discuss later in this article.
Exploring Code Splitting Techniques in Rspack
Project Structure
Here's a breakdown of some of the files in our project:
-
pages/
: This directory contains different pages of your app, such asHome.tsx
, andProductList.jsx
.-
App.jsx
: Where you define your primary routes and wrappers around your app.
-
-
package.json
: It contains metadata about the project, like the project name, version, dependencies, etc. -
rsbuild.config.mjs
: The configuration file for configuring rsbuild settings.
Let's Begin
Code splitting is a feature supported by Modern.js and it works alongside Rspack by splitting code into different "chunks". This is a crucial optimization technique which is used when bundling large applications. It works a bit differently than other frameworks.
Define Routes
The App.jsx
will define the routing for your application:
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
const Home = lazy(() => import('./Components/Home'));
const ProductList = lazy(() => import('./Components/ProductList'));
function App() {
return (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/products">Products</Link></li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/products" element={<ProductList />} />
</Routes>
</Suspense>
</Router>
);
}
export default App;
React's lazy function is combined with Suspense to dynamically import the component for each route. When the Route is rendered, React will automatically load the chunk containing the corresponding component.
Home Component
In the Home.jsx
file, import another chunk using React.lazy
. It will be automatically split into its own chunk by webpack.
// Components/Home.js
import React from 'react';
const Home = () => {
return <h1>Welcome to Our Online Store!</h1>;
};
export default Home;
ProductList Component
// /Components/ProductList
import React from 'react';
import { Link } from 'react-router-dom';
const products = [
// Dummy products data
{ id: 1, name: 'Product 1' },
{ id: 2, name: 'Product 2' },
{ id: 3, name: 'Product 3' },
];
const ProductList = () => {
return (
<div>
<h1>Product List</h1>
<ul>
{products.map((product) => (
<li key={product.id}>
<Link to={`/product/${product.id}`}>{product.name}</Link>
</li>
))}
</ul>
</div>
);
};
export default ProductList;
index.js
Your index.js
file is the starting point of your application:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import Home from './Components/Home';
console.log('index.js')
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
<Home/>
</React.StrictMode>,
);
rsbuild.confic.mjs
import { defineConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
export default defineConfig({
plugins: [pluginReact()],
mode: 'development',
entry: {
index: './src/index.jsx',
},
output: {
filename: '[name].bundle.js',
},
});
module.exports.defineConfig = defineConfig;
In this configuration React with Rspack will automatically split each page component (Home.jsx and ProductList.jsx) into its own chunk that gets loaded only when the corresponding route is navigated to using dynamic imports.
You can see this behavior in the Network tab of your browser's developer tools when you navigate between the different pages of your app. When you switch from /
to /products
, for example, you will notice the browser loading a new JavaScript file for that page.
Code splitting in React with Rspack enhances application performance by loading only necessary code chunks on demand. This way of splitting code ensures that the user only downloads the necessary code for the current page rather than all the code at once, substantially improving the load time of your application. Code splitting is just one piece of the optimization puzzle, but it's a significant one.
Be sure to join us on our ByteDance Open Source Discord Server!
Top comments (0)