Material-UIを使用する際の高速化を測る。
役割に応じたコンポーネントが用意されておりそれらをimportしつつUIを作り上げていく非常に便利なMaterial-UI(以下MUI)ですが、
一つの問題としてバンドルサイズが大きくなることが挙げられ、結果として開発環境の動作が重くなり、特にiconsパッケージを使用する場合に顕著になります。これはimport文の記述法によって左右されます。通常公式ドキュメントのコード例として掲載されているのは一つ目の方法です。
(Option1)
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
もう一つの記述法としては以下のようになり、こちらの方が速度は低下します。
(Option2)
import { Button, TextField } from '@material-ui/core';
公式ドキュメントによれば、二つ目の記述法を採用することでコードの重複が可読性を向上させるとしています。また、Babelプラグインを使えばOption2もOption1と同じ速さになるとのことです。
This option provides the best User Experience and Developer Experience:
UX: The Babel plugin enables top level tree-shaking even if your bundler doesn't support it.
DX: The Babel plugin makes startup time in dev mode as fast as Option 1.
DX: This syntax reduces the duplication of code, requiring only a single import for multiple modules. Overall, the code is easier to read, and you are less likely to make a mistake when importing a new module.
Minimizing Bundle Size - Material-UI
今回はOption2の記載方法でMUIのコンポーネントをimportする際に、Babelプラグインを導入することで速度の問題を解決する方法について書いていきます。
まずは以下のパッケージをインストールします。
yarn add -D babel-plugin-import react-app-rewired customize-cra
次に.babelrc.jsファイルを以下の内容でルートディレクトリに作成します。
const plugins = [
[
'babel-plugin-import',
{
libraryName: '@material-ui/core',
// Use "'libraryDirectory': ''," if your bundler does not support ES modules
libraryDirectory: 'esm',
camel2DashComponentName: false,
},
'core',
],
[
'babel-plugin-import',
{
libraryName: '@material-ui/icons',
// Use "'libraryDirectory': ''," if your bundler does not support ES modules
libraryDirectory: 'esm',
camel2DashComponentName: false,
},
'icons',
],
];
module.exports = { plugins };
そして次に、以下のconfig-overrides.jsファイルをルートディレクトリに作成します。
ESLintはデフォルトで無視されています。
/* eslint-disable react-hooks/rules-of-hooks */
/* config-overrides.js */
const { useBabelRc, override } = require('customize-cra');
module.exports = override(useBabelRc());
最後に、package.jsonのstartコマンドを以下のように修正します。
以上で、MUIでOption2のimport方法を使う準備が完了です。
現在のimport箇所を全て
import { Button, TextField } from '@material-ui/core';
のように変更しましょう。