Skip to content

Commit

Permalink
[docs] Improve Minimizing Bundle Size docs
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari committed Aug 2, 2019
1 parent 693c337 commit b3df097
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ use named imports and expect only a minimal set of Material-UI components in you
import { Button, TextField } from '@material-ui/core';
```

Be aware that tree-shaking is an optimization that is usually only applied to production
bundles. Development bundles will contain the full library which can lead to slower
startup times. This is especially noticeable if you import from `@material-ui/icons`.
⚠️ Be aware that tree-shaking is an optimization that is usually only applied to production
bundles. Development bundles will contain the full library which can lead to **slower
startup times**. This is especially noticeable if you import from `@material-ui/icons`.
Startup times can be approximately 6x slower than without named imports from the top-level API.

If this is an issue for you, you have various options:
Expand All @@ -37,66 +37,100 @@ import { Button, TextField } from '@material-ui/core';
use:

```js
// 🚀 Fast
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
```

This is the option we document in **all** the demos as the one that requires no configuration. Head to [Option 2](#option-2) for the option we recommend.

While importing directly in this manner doesn't use the exports in [`@material-ui/core/index.js`](https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/index.js), this file can serve as a handy reference as to which modules are public.

Be aware that we only support first and second level imports. Anything below is considered
private and can cause module duplication in your bundle.

```js
// OK
// OK
import { Add as AddIcon } from '@material-ui/icons';
import { Tabs } from '@material-ui/core';
// ^^^^ 1st or top-level

// OK
// OK
import AddIcon from '@material-ui/icons/Add';
import Tabs from '@material-ui/core/Tabs';
// ^^^^ 2nd level

// NOT OK
// NOT OK
import TabIndicator from '@material-ui/core/Tabs/TabIndicator';
// ^^^^^^^^^^^^ 3rd level
```

### Option 2

**Important note**: This is only supported for `@material-ui/icons`.
We recommend this approach if you often restart your development build.
We **recommend** this option as providing the best DX and UX.
However, you need to apply the following steps correctly.

Another option is to keep using named imports, but still have shorter
start up times by using `babel` plugins.
#### 1. Configure Babel

Pick one of the following plugins:

- [babel-plugin-import](https://github.com/ant-design/babel-plugin-import) with the following configuration:

```js
[
'babel-plugin-import',
{
libraryName: '@material-ui/icons',
libraryDirectory: 'esm', // or '' if your bundler does not support ES modules
camel2DashComponentName: false,
},
];
plugins: [
[
'babel-plugin-import',
{
libraryName: '@material-ui/core',
libraryDirectory: 'esm', // or '' if your bundler does not support ES modules
camel2DashComponentName: false,
},
'core',
],
[
'babel-plugin-import',
{
libraryName: '@material-ui/icons',
libraryDirectory: 'esm', // or '' if your bundler does not support ES modules
camel2DashComponentName: false,
},
'icons',
],
],
```
- [babel-plugin-transform-imports](https://www.npmjs.com/package/babel-plugin-transform-import) has a different api than `babel-plugin-import` but does same thing.
- [babel-plugin-transform-imports](https://www.npmjs.com/package/babel-plugin-transform-imports) with the following configuration:

```js
[
'transform-imports',
plugins: [
'babel-plugin-transform-imports',
{
'@material-ui/core': {
transform: '@material-ui/core/esm/${member}',
// for bundlers not supporting ES modules use:
// transform: '@material-ui/core/${member}',
preventFullImport: true,
},
'@material-ui/icons': {
transform: '@material-ui/icons/esm/${member}',
// for bundlers not supporting ES modules use:
// transform: '@material-ui/icons/${member}',
preventFullImport: true,
},
},
];
],
```

#### 2. Convert all your imports

Finally, you can convert your exisiting codebase to this option with our [top-level-imports](https://github.com/mui-org/material-ui/blob/master/packages/material-ui-codemod/README.md#top-level-imports) codemod.
It will perform the following diffs:

```diff
-import Button from '@material-ui/core/Button';
-import TextField from '@material-ui/core/TextField';
+import { Button, TextField } from '@material-ui/core';
```

## ECMAScript

The package published on npm is **transpiled**, with [Babel](https://github.com/babel/babel), to take into account the [supported platforms](/getting-started/supported-platforms/).
Expand Down
4 changes: 4 additions & 0 deletions packages/material-ui-codemod/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ Converts all `@material-ui/core` imports more than 1 level deep to the optimal f
find src -name '*.js' -print | xargs jscodeshift -t node_modules/@material-ui/codemod/lib/v4.0.0/optimal-imports.js
```

Head to https://material-ui.com/guides/minimizing-bundle-size/ to understand when it's useful.

#### `top-level-imports`

Converts all `@material-ui/core` submodule imports to the root module:
Expand All @@ -74,6 +76,8 @@ Converts all `@material-ui/core` submodule imports to the root module:
find src -name '*.js' -print | xargs jscodeshift -t node_modules/@material-ui/codemod/lib/v4.0.0/top-level-imports.js
```

Head to https://material-ui.com/guides/minimizing-bundle-size/ to understand when it's useful.

### v1.0.0

#### `import-path`
Expand Down

0 comments on commit b3df097

Please sign in to comment.