One small change in Antd imports that reduces the bundle size by 25%

I currently joined a project and started working on its web app written in React, using Ant Design (package: antd) as the UI library. While everything else is well and good, the project clearly had an issue with its bundle size. It was shipping megabytes (already compressed, ofc) of code to the client-side. So I thought as someone who's interested in making clean and fast websites, I ought to investigate.

This post is the first in the series of me optimizing the performance of this particular project. At the moment of writing, I'm 2 months in and have been making significant progress.

Right of the bat, building the project (using Vite) gives me the following results:

... many more lazy-loaded modules build/assets/index.42e80c1c.js 75.08 KiB / gzip: 21.51 KiB build/assets/index.dd3abd12.js 63.42 KiB / gzip: 18.25 KiB build/assets/index.dde1f4ba.js 106.44 KiB / gzip: 36.13 KiB build/assets/index.a862fc09.js 133.82 KiB / gzip: 36.82 KiB build/assets/index.2abc25c6.js 178.74 KiB / gzip: 52.90 KiB # These are eagerly loaded build/assets/index.f6ef2bbb.css 346.10 KiB / gzip: 60.39 KiB build/assets/index.40bb55d8.js 483.83 KiB / gzip: 136.26 KiB build/assets/browser.a002aaef.js 685.69 KiB / gzip: 187.29 KiB build/assets/index.cbcdbec4.js 1566.62 KiB / gzip: 440.35 KiB build/assets/vendor.e8ce99ba.js 5377.73 KiB / gzip: 1575.32 KiB

Given the context that this webapp is mainly an info app (making API requests and displaying the results on the UI), shipping over 2mb of JS code on initial load is, to my standard, not good.

I then decided to install rollup-plugin-visualizer which would help me take a deeper look into the code that is being bundled. And I found something interesting.

Inside the antd module, there were 2 huge chunks called lib and es which have items that are almost if not identical:

Untitled

This is a clear sign that we were having troubles with treeshaking for Antd. Having some experiences dealing with ES modules, and seeing that the codebase were importing items from both antd/es/* and antd/lib/*, I suspected that the bundle size should reduce greatly if we were to just convert all antd/lib import paths to antd/es.

A quick Google search confirmed my suspicion on the nature of the problem: This GitHub issue's marked answer

So the only thing left to do is a Search All & Replace using Vscode:

Untitled

And boom! The vendor.js file, which contains all the code bundled from our beloved node_modules, is now smaller than before. A 25% reduction, that is!

build/assets/index.f6ef2bbb.css 346.10 KiB / gzip: 60.39 KiB build/assets/index.6c0b1689.js 483.83 KiB / gzip: 136.26 KiB build/assets/browser.532ccd09.js 685.69 KiB / gzip: 187.29 KiB build/assets/index.7f70652c.js 1566.60 KiB / gzip: 440.32 KiB build/assets/vendor.488cf11a.js 4043.13 KiB / gzip: 1203.30 KiB
Bonus: Preventing other devs from importing antd/lib

You can add the following rule to your Eslint/OXLint config file:

"no-restricted-imports": [ "error", { "paths": [ { "name": "antd/lib", "message": "Don't import from 'antd/lib/...'. Use 'antd/es/...' instead." } ], "patterns": [ { "group": ["antd/lib/*"], "message": "Don't import from 'antd/lib/...'. Use 'antd/es/...' instead." } ] } ]