Although I followed the steps explained in the docs (see here) to enable Tree Shaking, it seems to have no effect. I'm using Webpack 4
with ts-loader
for TypeScript
. The library in question is material-ui
. In their docs (see How to reduce the bundle size?) they recommend to "import directly from material-ui/
to avoid pulling in unused modules" and later they add "Both of the options should be temporary until you add tree shaking capabilities to your project.". So I assume that Tree Shaking should have some effect.
To be clear: They recommend to import like this:
import RaisedButton from "material-ui/RaisedButton";
And not like this:
import {RaisedButton} from "material-ui";
What I did:
"sideEffects":false
entry to my project's package.json
file. And made sure the spelling is correct.mode: "production"
, which Webpack 4 allows to use instead of UglifyJsPlugin
("As of webpack 4, this is also easily toggled via the "mode" config option, set to "production".")Result: Nothing. No reduction in size. So maybe I'm doing something wrong?
For the benchmark lovers: This is what a single RaisedButton
costs in terms of bundle size. Without minification (i.e. production mode):
Initial (in mode "development"):
1,63 MiB (No Material UI)
MuiThemeProvider
1,94 MiB -> +0,31 (`import {MuiThemeProvider} from "material-ui/styles";`)
1,92 MiB -> +0,29 (`import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';`)
RaisedButton
3,07 MiB -> +1,13 (`import {RaisedButton} from "material-ui";`)
2,03 MiB -> +0,09 (`import RaisedButton from "material-ui/RaisedButton";`)
And with minification (no compression):
Initial (in mode "production"):
284 KiB (No Material UI)
MuiThemeProvider
371 KiB -> +087 (`import {MuiThemeProvider} from "material-ui/styles";`)
367 KiB -> +077 (`import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';`)
RaisedButton
705 KiB -> +338 (`import {RaisedButton} from "material-ui";`)
400 KiB -> +033 (`import RaisedButton from "material-ui/RaisedButton";`)
And with Tree Shaking enabled:
705 KiB (`import {RaisedButton} from "material-ui";`)
400 KiB (`import RaisedButton from "material-ui/RaisedButton";`)
I.e: No effect at all.
Add a "sideEffects" property to your project's package. json file. Use the production mode configuration option to enable various optimizations including minification and tree shaking.
In webpack, tree shaking works with both ECMAScript modules (ESM) and CommonJS, but it does not work with Asynchronous Module Definition (AMD) or Universal Module Definition (UMD).
When and how to use tree-shaking? 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.
As @qx3 wrote, I've been able to get it by adding:
alias: { '@material-ui/core': '@material-ui/core/es' }
in my webpack config.
Note the '@' prefix and the '/core' suffix to adapt to the new naming of the library. This simple little thing, helped me to get rid of some bytes and enabled the team to write the '@material-ui/core' imports in a full esm compliant way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With