Component-based code splitting
The open source library
react-loadable provides a React-friendly API for code splitting, and lets you add breakpoints with just a few lines of code. If you're using
create-react-app, Webpack automatically takes care of splitting the bundle and loading chunks on demand under the hood.
Here’s how it works: suppose we want to load and render the component
SettingsPage on demand, when the user clicks on a particular or navigates to a particular route. All we need to is wrap it using
react-loadable as follows:
Now we can use
AsyncSettingsPage just like a normal React component. The module
AsyncSettingsPage is rendered for the first time.
While the chunk is loading, the component
Loading is rendered in its place. Here’s a sample implementation of
error is set to a non-null value if the chunk fails to load.
Chunking multiple components together
There are some cases where simple component-based splitting may not be enough. For instance, you may have a set of components that are almost always used together in a several different features. In such a case, it makes sense to have a single chunk which contains the entire set of related components.
Here’s how we might normally export a set of related components:
Assuming the above code is in the file
item-list/index.js, we can create another file
item-list/async.js with the following contents:
The key change here is in the dynamic
import: instead of importing a single component, we are importing all of
index.js and extracting the required component in the promise callback.
Chunk naming and optimization
File sizes after gzip:
396.71 KB build/static/js/main.3a8842c0.js
178.51 KB build/static/css/main.e32b4522.css
68.31 KB build/static/js/6.af93367f.chunk.js
44.34 KB build/static/js/2.6a7f1417.chunk.js
23.61 KB build/static/js/1.bdfdcd83.chunk.js
22.24 KB build/static/js/3.d9e4ee99.chunk.js
19.29 KB build/static/js/4.a66b3cdb.chunk.js
17.1 KB build/static/js/5.f1ce26f7.chunk.js
7.63 KB build/static/js/8.2e807534.chunk.js
6.71 KB build/static/js/9.409015da.chunk.js
5.09 KB build/static/js/7.1b95d8e8.chunk.js
1.71 KB build/static/js/0.6bea2af7.chunk.js
1 KB build/static/js/10.ce9f2434.chunk.js
After looking at this output, we might want to remove some of the last few chunks since they’re really small. But we don’t know which split is causing which chunk to be created. This is where chunk naming can be helpful.
We can use a magic comment inside the
import that tells Webpack to use the given name for a specific chunk:
Once all the chunks are named, we can identify the splits that lead to smaller chunks:
File sizes after gzip:
312.09 KB build/static/js/main.491eaaf4.js
181 KB build/static/css/main.ac06cedb.css
68.88 KB build/static/js/settings.1525d075.chunk.js
45.08 KB build/static/js/alerts.0f5ad4d6.chunk.js
23.62 KB build/static/js/profile.199c7f90.chunk.js
22.24 KB build/static/js/history.07ccea31.chunk.js
19.3 KB build/static/js/actions.903378a5.chunk.js
8.87 KB build/static/js/events.f540de3a.chunk.js
7.62 KB build/static/js/colors.89aa1e6f.chunk.js
6.7 KB build/static/js/posts.929f04fc.chunk.js
5.1 KB build/static/js/post-details.6c133f77.chunk.js
1.71 KB build/static/js/friend-list.be516e45.chunk.js
1.01 KB build/static/js/edit-avatar.33a4ff21.chunk.js
At this point, we can choose to remove or combine some of the smaller chunks (< 20–30 KB in size), since the overhead of loading a 5 KB chunk might be higher than combining it with one of the larger chunks. Play around with different splits and see what works best for you.
Analyzing the Bundle Size
npm install --save source-map-explorer
package.json, add the following line to
"analyze": "source-map-explorer build/static/js/main.*",
Then to analyze the bundle run the production build then run the analyze script.
npm run build
npm run analyze
Look for the largest contributors to the bundle size as possible candidates for code-splitting. Also consider removing or pruning large dependencies from
Here are steps for achieving effective code splitting in React applications:
- Chunk multiple components that are frequently used together into a single file using the
- Name your chunk using the magic comment
/* webpackChunkName: xxx */and optimize bundle sizes so that they are neither too small nor too large.
source-map-explorerto identify possible candidates for code splitting.
I’ve skipped over many details to keep this article short and focus on the practical aspects of code splitting. Following are some good places to learn more about the topic:
- React official docs: https://reactjs.org/docs/code-splitting.html
- Chunk naming in Webpack: https://github.com/webpack/webpack/tree/master/examples/code-splitting-specify-chunk-name