[SelectField] Introduce new component
See original GitHub issueMinimum example of React Material-UI with the only TextField component imported - result bundle size is 250Kb!
https://github.com/pqr/react-mui-treeshake-does-not-work
webpack-bundle-analyzer shows everything is imported, nothing is tree shaked.
According to documentation https://material-ui.com/guides/minimizing-bundle-size/ tree-shaking should work, quote:
Tree-shaking of Material-UI works out of the box in modern frameworks. Material-UI exposes its full API on the top-level material-ui import. If you’re using ES6 modules and a bundler that supports tree-shaking (webpack >= 2.x, parcel with a flag) you can safely use named imports and still get an optimised bundle size automatically:
import { Button, TextField } from '@material-ui/core';
But as shown in this minimum example it does not work out of the box. I did several experiments, read through issues and StackOverflow and failed to find a solution.
- [+] The issue is present in the latest release.
- [+] I have searched the issues of this repository and believe that this is not a duplicate.
Current Behavior 😯
Bundle size of minimum app with the only TextField imported is about 250Kb, everything is included into bundle (analized with webpack-bundle-analyzer
Expected Behavior 🤔
Bundle should not contain any code not related to the only imported TextField, tree shake to be working
Steps to Reproduce 🕹
git clone git@github.com:pqr/react-mui-treeshake-does-not-work.git
cd react-mui-treeshake-does-not-work
npm install
npm run build
npm run analyze
Your Environment 🌎
Tech | Version |
---|---|
Material-UI | v4.11 |
React | 16.13.1 |
Browser | Any |
TypeScript | No |
Webpack | 4.43 |
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:5 (4 by maintainers)
Top GitHub Comments
@pqr wants his app to only include the code he needs. In his bundle size analysis
he noticed a lot of components with no clear relation to displaying an input. He went on assuming that it’s because tree shaking is broken. Wrong.
So from what I understand, we are covering the same root pain point with the SelectField component proposal. It’s only the interpretation of the origin of the pain from the author that is wrong, the underlying issue is still present: text field shouldn’t bundle select.
The proposed solution is:
Our team was also really caught off guard by this. We noticed the bundle sizes for our form pages were really bloated despite us only using text fields and buttons from material-ui. Spent ages trying to track down where the bundler was getting confused and importing Selects and Modals, only to find that TextField includes Select, Modal, and their many dependencies by default.
For any other devs stumbling across this issue, here’s a bandaid solution that you can use to greatly reduce the size of TextFields while material-ui works on an official fix. This custom component simply follows the structure of material-ui’s TextField component but removes any references to Select and requires that the variant component is provided as a prop (This way, only the variant type you use will be included in your bundle, rather than all 3 standard, outlined, and filled variant components being included by default):
ComposableTextField.tsx
Simply replace any references to TextField with this ComposableTextField component instead. And make sure to pass in the InputComponent variant you’d like to use:
Replace this:
With this:
As a side note, the material-ui Text Fields documentation does mention that you can use the lower level components to better customize your TextFields, but perhaps it would also be worth mentioning that you can use these lower level components to reduce your bundle size in the Minimizing Your Bundle Size documentation.