mcpField
T
tree-shaking

tree-shaking

github.com/patternsdev開発2571.5k 回インストール28 週間前に更新
リポジトリ

tree-shaking について

JavaScript 開発者向けに、バンドル時に未使用コードを除去してサイズを抑える方法を解説します。ES モジュールのインポートや副作用、その死コード除去への影響を扱います。

主な機能

  1. 01バンドル時に未使用コードを除去
  2. 02ES2015 の import/export 構文を使用
  3. 03名前付きインポートを優先
  4. 04適切な場合に副作用なしと指定
  5. 05副作用が除去に与える影響を解説

活用シーン

  1. 01JavaScript バンドルのサイズ削減
  2. 02未使用の依存コードの同梱を回避
  3. 03ページのダウンロードと解析を改善

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/patternsdev/skills --skill tree-shaking

インストール後、Claude Code で/tree-shakingを入力して読み込まれたか確認します。

詳細

Tree Shaking

アプリケーション内でどこにも使われていないコードが、バンドルに追加されることがあります。このような不要なコードは、バンドルのサイズを減らし、余分なデータの読み込みを防ぐために取り除けます。バンドルに追加する前に不要なコードを取り除く処理を、ツリーシェイキングと呼びます。

使用する場面

  • バンドルに、インポートしたモジュールの未使用コードが含まれている場合に使用します
  • JavaScript バンドルを軽量に保ち、読み込みパフォーマンスを向上させるのに役立ちます

手順

  • ES2015 の import/export 構文を使用します。ツリーシェイキングできるのは ES モジュールのみです
  • 効果的なツリーシェイキングを可能にするため、モジュール全体をインポートするのではなく、名前付きインポートを使用します
  • 適切な場合は、package.json でパッケージに副作用がないことを指定します
  • 副作用のあるモジュールは安全にツリーシェイキングできないことに注意してください

詳細

概念

ツリーシェイキングは、最終的な JavaScript バンドルから、決して使われないコードを取り除くことを目的としています。適切に行えば、JavaScript バンドルのサイズを減らし、ダウンロードや解析にかかる時間を短縮できます。また、場合によっては実行時間も短縮できます。webpack や Rollup などのモジュールバンドラーを使う最新の JavaScript アプリの多くでは、バンドラーが不要なコードを自動的に取り除くことが期待されます。

アプリケーションとその依存関係を抽象構文木として考えてみましょう(構文木を「振る」ことで最適化します)。ツリー内の各ノードは、アプリに機能を提供する依存関係です。ツリーシェイキングでは、入力ファイルはグラフとして扱われます。グラフ内の各ノードは、コード内で「パート」と呼ばれるトップレベルの文です。ツリーシェイキングは、エントリーポイントから開始し、たどったパスをバンドルに含めるものとしてマークするグラフの走査です。

各コンポーネントは、シンボルを宣言したり、シンボルを参照したり、ほかのファイルに依存したりできます。「パート」もそれぞれ、副作用があるかどうかをマークされます。たとえば、let firstName = 'Jane' という文は、firstName がどこからも必要とされていない場合に、取り除いても確認可能な違いが生じないため、副作用がありません。一方、let firstName = getName() という文には副作用があります。firstName がどこからも必要とされていなくても、getName() の呼び出しを取り除くとコードの意味が変わってしまうためです。

インポート

ES2015 のモジュール構文(import と export)で定義されたモジュールのみ、ツリーシェイキングできます。モジュールのインポート方法によって、そのモジュールをツリーシェイキングできるかどうかが決まります。

ツリーシェイキングは、エントリーポイントファイルの副作用があるすべてのパートをたどることから始まり、新しいセクションに到達するまでグラフの辺をたどっていきます。走査が完了すると、JavaScript バンドルには走査中に到達したパートのみが含まれます。それ以外の部分は除外されます。

たとえば、次の utilities.js ファイルがあるとします。

export function read(props) {
  return props.book
}

export function nap(props) {
  return props.winks
}

次に、以下の index.js ファイルがあるとします。

import { read } from 'utilities';

eventHandler = (e) => {
  read({ book: e.target.value })
}

この例では、nap() は重要ではないため、バンドルには含まれません。

副作用

ES6 モジュールをインポートすると、そのモジュールはただちに実行されます。コード内でモジュールのエクスポートをどこからも参照していなくても、実行中にモジュール自体がグローバルスコープに影響を与えることがあります(ポリフィルやグローバルスタイルシートなど)。これを副作用と呼びます。モジュール自体のエクスポートを参照していなくても、モジュールが何らかの値をエクスポートしている場合は、インポート時の特別な挙動により、ツリーシェイキングできません。

Webpack のドキュメントでは、ツリーシェイキングについての明確な説明と、ツリーシェイキングを損なわない方法を確認できます。

出典

コメント