question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Material UI Icons are not being tree shook

See original GitHub issue
  • I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

I use WebPack and have Tree Shaking setup, I only use a few icons from material-ui-icons, with imports like like import {Edit, AddBox} from 'material-ui-icons'; and expect the tree shaking algorithm to strip out all the unused icons from the bundle.

Current Behavior

Analyzing the contents of my production bundle I see that the entirety of material-ui-icons is used in my bundle, including piles of icons I definitely do not use.

And I manually verified that icons I do not use are present in the bundle.

screen shot 2018-03-30 at 3 02 07 am

Looking at the contents of node_modules/material-ui-icons/, I notice that while an index.es.js exists and is being used, the modules being imported themselves appear to be CommonJS modules.

Given the “Use ES2015 module syntax (i.e. import and export).” limitation of tree shaking, I have a feeling that the reason .

It’s a side topic but I just realized that the analysis of the Material-UI import looks strange as well. Material UI has an entire material-ui/es/ folder and an index.es.js that is being imported, but it looks as if all the modules are being imported from the CommonJS modules instead of the modules inside material-ui/es/.

Your Environment

Tech Version
Material-UI 1.0.0-beta.38
Material-UI-Icons 1.0.0-beta.36
React 16.2.0
WebPack 3.11.0
Babel 6.26.0

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:6
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

7reactions
rosskevincommented, May 3, 2019

I want to confirm that tree shaking worksin production only!

TL;DR

  • the bundle is appropriately built by material-ui
  • the following only applies to index based named imports (we use module/esm builds only)
  • the problem originates with webpack and lack of tree shaking in development

Background

  • We were seeing slowdowns in dev, and even failures to run cucumber tests on our local machines
  • Network panel in the browser noted very long time to serve files from webpack (tried in both webpack-dev-server and webpack-plugin-serve)
  • We recently switch to all index based imports
  • Our production bundle is optimized and tree-shaken and does not exhibit problems
  • Upon analysis with webpack-bundle-analyzer of our development bundle, we noticed a gz size of 14mb and a stat size of 80mb, of which the @material-ui/icons packages was 32mb.

Cause

  • it appears if importing from an index, the full module is included by webpack when in development mode
  • it appears if using webpack aliases that the node_module dependencies will be duplicated (we have an app repo and alias projects from another monorepo), this meant (amongst other dependencies) that we duplicated all @material-ui dependencies
  • stat size of @material-ui/icons is 16mb. Two versions of that accounted for 32mb of the ~80mb stat size.

Here is the result of aliasing multi repo dependencies to just the local app node_modules, you can see the sheer size of @material-ui/icons accounting for ~30% of the stat size:

icons-size

Solution

This applies to dev only, and I repeat - it has no bearing on a production build. Production builds with tree shaking work just fine when importing from an esm index.

If you want to optimize dev builds:

  • make sure that you are careful with webpack aliases
  • add webpack aliases (if you are using other src aliases locally) to ensure only one version of common libraries are used (for example, react, react-dom, and material-ui packages were duplicated by both code bases and an alias to the nearest node_modules for these dependencies cured the duplication)
  • since the @material-ui/icons happen to have a large file count and stat size, I recommend optimizing your development builds by using direct file path imports.

e.g. replace import { Home } from '@material-ui/icons' with import Home from '@material-ui/icons/Home'

I hope my few hours of hair pulling helps someone out!

Once again, this has no bearing on production, and only applies to optimizing a dev build.

3reactions
verekiacommented, Sep 18, 2018

For posterity I just ran the following tests on my project, by changing the sideEffects in the package.json of @material-ui/core and @material-ui/icons directly in node_modules. Bundle sizes uncompressed:

Tests on core:

  • import { ... } from '@material-ui/core' with "sideEffects": true in core : 956kb
  • import { ... } from '@material-ui/core' with "sideEffects": false in core : 790kb
  • import Foo from '@material-ui/core/Foo' with "sideEffects": true in core : 789kb
  • import Foo from '@material-ui/core/Foo' with "sideEffects": false in core : 789kb

Tests on icons:

  • import { Bar } from '@material-ui/icons' with "sideEffects": true in icons : 3.87mb
  • import { Bar } from '@material-ui/icons' with "sideEffects": false in icons : 793kb
  • import Bar from '@material-ui/icons/Bar' with "sideEffects": true in icons : 789kb
  • import Bar from '@material-ui/icons/Bar' with "sideEffects": false in icons : 789kb

At first I thought tree-shaking was not working because bundle size are slightly different when using the different import styles, but that difference is negligible (789 -> 790 for core and 789 -> 793 for icons), but this is likely due to the code added by Webpack to tree shake. The difference is massive when turning off tree-shaking so it definitely works.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Material UI Icons are not being tree shook #10857 - GitHub
I use WebPack and have Tree Shaking setup, I only use a few icons from material-ui-icons , with imports like like import {Edit,...
Read more >
Minimizing bundle size - Material UI - MUI
Tree -shaking of MUI works out of the box in modern frameworks. ... This is especially noticeable if you use named imports from...
Read more >
Material UI Icons not rendering correctly - Stack Overflow
If your environment doesn't support tree-shaking, the recommended way to import the icons is the following:
Read more >
React/Webpack: From MB to KB. How we solved our bundling ...
Last mistake that was noticeable just from this view was that we were not tree shaking. It's evident from Material-UI icons section we...
Read more >
Tree-shaking (material-ui) : [ERR_REQUIRE_ESM]
Hi,. Using the bundle analyser I see that Material UI takes up nearly 400kb of space, and it appears to includes the entirety...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found