43

I'm using ant design library for my react application.

And I've faced with huge imports, that hurts my bundle (currently 1.1 mb in minified version because of ant-design lib).

How can I differently import antd components through all my app?

enter image description here

UPDATE:

Seems antd has some huge or non optimized modules. Here the thing - only difference is import Datepicker module, and.. boom! + almost 2MB (in dev bundle ofc.)

enter image description here

1
  • I am using antd for a small project with only two route. The project size is 1.6MB after uglify. Kindly provide an answer here if you able to solve this problem.
    – Sisir
    Commented Oct 1, 2018 at 8:11

7 Answers 7

23

UPD: the underlying issue seems to be resolved for the new (4.0) version of antd.
Therefore, if you try to resolve this issue for the earlier versions, the recommended way is to migrate onto antd 4

Previous answer:

At the moment, a huge part of antd dist is SVG icons.
There is no official way to deal with it yet (check the issue on github).

But a workaround exists.

  1. Adapt webpack to resolve icons differently. In your webpack config:
module.exports = {
  //...
  resolve: {
    alias: {
      "@ant-design/icons/lib/dist$": path.resolve(__dirname, "./src/icons.js")
    }
  }
};
  1. Create icons.js in the folder src/ or wherever you want it. Be sure it matches the alias path!
    In this file, you define which icons antd should include.
export {
  default as DownOutline
} from "@ant-design/icons/lib/outline/DownOutline";

It's also possible to do this with react-app-rewired (create-react-app modifications) within config-overrides.js

2
  • props to @Tobias Lins for this solution Commented Feb 15, 2019 at 10:39
  • how will this work on vite ?
    – Sushilzzz
    Commented Mar 30, 2022 at 7:13
12

1) Prevent antd to load the all moment localization. Add webpack plugin and configure it in webpack.config.js like the follow:

plugins: [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /ru/),
],
resolve: {
    alias: {moment: `moment/moment.js`}
},
target: `web`
}

2) Use the same moment version as in antd library.

3) Use modularized antd Use babel-plugin-import

// .babelrc or babel-loader option
{
  "plugins": [
    ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }]
    // `style: true` for less
  ]
}

I use BundleAnalyzerPlugin to analyze the bundle.

plugins: [new BundleAnalyzerPlugin()]

12

Looking at the docs https://ant.design/docs/react/getting-started#Import-on-Demand there is a recommedation to import individual components on demand. So, you can try and replace

import { Button} from 'antd' 

with

import Button from 'antd/lib/button'
5
  • 9
    This is automatically taken care of when using babel-plugin-import Commented Apr 24, 2019 at 10:31
  • I found github.com/vazco/uniforms/issues/219 helpful.
    – B--rian
    Commented Oct 7, 2019 at 12:33
  • 1
    @DaveHowson Yes but babel-plugin-import can be used with popular tools like create-react-app only by ejecting. Read this issue on GitHub for more info. Commented Nov 26, 2019 at 18:07
  • I tried this approach in import { Collapse } from "antd/lib/collapse"; and destructuring const { Panel } = Collapse; but getting error TypeError: Cannot destructure property 'Panel' of 'antd_lib_collapse__WEBPACK_IMPORTED_MODULE_3__.Collapse' as it is undefined.
    – era s'q
    Commented Mar 15, 2021 at 8:07
  • this definitely helped. even on 5.2.3 it was taking a long time to load.
    – juniortan
    Commented Feb 28, 2023 at 1:53
6

I reduced my bundle size by 500KB by editing config-override.js like so:

config-override.js

const { override, fixBabelImports } = require('customize-cra');
const path = require('path');

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css'
  }),
  // used to minimise bundle size by 500KB
  function(config, env) {
    const alias = config.resolve.alias || {};
    alias['@ant-design/icons/lib/dist$'] = path.resolve(__dirname, './src/icons.js');
    config.resolve.alias = alias;
    return config;
  }
);

./src/icons.js

/**
 * List all antd icons you want to use in your source code
 */
export {
  default as SearchOutline
} from '@ant-design/icons/lib/outline/SearchOutline';

export {
  default as CloseOutline
} from '@ant-design/icons/lib/outline/CloseOutline';

export {
  default as QuestionCircleOutline
} from '@ant-design/icons/lib/outline/QuestionCircleOutline';

export {
  default as PlayCircleOutline
} from '@ant-design/icons/lib/outline/PlayCircleOutline';

export {
  default as PauseCircleOutline
} from '@ant-design/icons/lib/outline/PauseCircleOutline';

export {
  default as LoadingOutline
} from '@ant-design/icons/lib/outline/LoadingOutline';

Before

Screen Shot 2019-11-05 at 2 56 54 pm

After

Screen Shot 2019-11-05 at 2 56 48 pm

1
  • Hi @Jan, How can we know which icons should we import in icons.js file. I have an InputNumber and also Select dropdown. but the arrows are not visible :-| Any help/suggestion would be appreciated.
    – stafan
    Commented Jan 31, 2020 at 18:59
3

Those few components are certainly not 1.2M together. Looks like you are importing the whole library when you only need a few components.

To get antd to load only the needed modules you should use babel-plugin-import. Check your console log for the "You are using a whole package of antd" warning described at that link.

Check out the docs for Create-React-App for how to implement it if you're using CRA.

4
  • My console is clean as baby tear. And I'm already using babel-plugin-import. Anyway bundle still huge. Will try to reformat my imports with import Thing from 'antd/lib/thing'. It will reduce size, probably, but definitely will cause many import strings.
    – WebArtisan
    Commented Feb 12, 2018 at 14:08
  • Well something is wrong with your setup. My bundles usually has all of the components you list except Layout, plus many more. antd is 348kB uncompressed. The entire app including antd, React and stupidly large lodash plus lots of other stuff is 350kB gzipped.
    – Jesper We
    Commented Feb 12, 2018 at 14:29
  • A tip: github.com/chrisbateman/webpack-visualizer is a simple plugin that will give you a very good visual report of your bundle where you can drill down inside of modules. You can use it to see which parts of Antd are actually included.
    – Jesper We
    Commented Feb 12, 2018 at 14:33
  • Had the same problem as WebArtisan. Followed the instructions for CRA step by step. It didn't help the bundle still contains components that I don't use. Here are screenshots of my package.json. config-overrides.js, and the visualisation of bundle.js: imgur.com/a/Pnpm4I3
    – Zapnuk
    Commented Jul 19, 2018 at 11:44
0

Try using code splitting using webpack and react router. It will help you to load the modules asynchronously. This is the only solution helped me to improve the page load time when using ant framework.

1
  • I am also thinking of using react-loadable for async loading with antd but the Ant documentation talks about using react-app-rewire for modular imports. I am wondering if I should do both or just react-loadble for dynamic component import. I feel like code splitting alone should help but this thread worries me - github.com/ant-design/ant-design/issues/12011 Commented Apr 6, 2019 at 23:44
0

Issue which caused large bundle size has been fixed in Ant Design 4.0.

Quoting from the release announcement.

Smaller size

In antd @ 3.9.0, we introduced the svg icon ([Why use the svg icon?] ()). The icon API using the string name cannot be loaded on demand, so the svg icon file is fully introduced, which greatly increases the size of the packaged product. In 4.0, we adjusted the icon usage API to support tree shaking, reducing the default package size of Antant by about 150 KB (Gzipped).

In order to install Ant Design 4 you have to do following

npm install [email protected]
// or  in yarn
yarn add [email protected]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.