コンテンツにスキップ

JavaScript/Tree Shaking

出典: フリー教科書『ウィキブックス(Wikibooks)』

Tree Shaking は、JavaScript のモジュールバンドルツール(例: WebpackRollup)において、未使用のコード(デッドコード)を削除し、最適化を図る技術です。この機能は主に ECMAScript Module(ESM)の静的構造を活用しています。

以下では、Tree Shaking の基本原理、動作の仕組み、注意点、実際の手法について包括的に解説します。

Tree Shaking の基本原理

[編集]

Tree Shaking の基本的な考え方は、プログラム全体を解析し、実際に使用されていないコードを除外することです。これにより、最終的なバンドルサイズを縮小し、ロード時間を短縮します。

Tree Shaking を可能にするポイント:

  • ESM の静的構造: ESM は importexport によって明示的に依存関係を記述します。
  • 静的解析: ツールがコード全体を解析し、依存関係を追跡できる。
  • 副作用の有無: 副作用のないコードを削除することで安全に最適化を行う。

Tree Shaking の仕組み

[編集]

必要な条件

[編集]
  1. ESM の使用
    Tree Shaking は ESM の importexport を利用して動作します。CommonJSrequiremodule.exports)は動的解析が必要なため、Tree Shaking に適しません。
  2. ツールのサポート
    Tree Shaking を実行するには、以下のようなモジュールバンドラが必要です:
    • Rollup: ESM をネイティブにサポートし、Tree Shaking に特化。
    • Webpack: バージョン 2 以降で Tree Shaking をサポート。
  3. コードが副作用を持たない
    副作用のあるコードは安全に削除できないため、削除の対象外になります。これを指定するには、package.jsonsideEffects フィールドを設定します。

実際の手法

[編集]

モジュールの設計

[編集]

コードを Tree Shaking に対応させるには、適切にモジュールを設計する必要があります。 未使用のコードを明示的に区別するために、モジュールごとに分割します。

例: 名前付きエクスポート

[編集]
math.js
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;
app.js
import { add } from './math.js';
console.log(add(2, 3)); // multiply は使われていないので削除される

例: デフォルトエクスポートを避ける

[編集]

デフォルトエクスポートでは、使用していない部分の特定が難しくなります。

// BAD: 削除できない可能性がある
export default {
  add: (a, b) => a + b,
  multiply: (a, b) => a * b
};

バンドルツールの設定

[編集]

Rollup の設定例

[編集]

Rollup は Tree Shaking に最適化されたツールです。

rollup.config.js
export default {
  input: 'src/main.js',
  output: {
    file: 'dist/bundle.js',
    format: 'es'
  },
  treeshake: true
};

Webpack の設定例

[編集]

Webpack では modeproduction に設定するだけで Tree Shaking が有効になります。

webpack.config.js
module.exports = {
  mode: 'production',
  entry: './src/main.js',
  output: {
    filename: 'bundle.js'
  },
  optimization: {
    usedExports: true
  }
};

副作用の排除

[編集]

副作用のあるコードは削除されないため、モジュールが副作用を持たないことを明示します。

package.jsonsideEffects フィールドを設定します。

例: 副作用のないモジュール

[編集]
package.json
{
  "name": "my-library",
  "version": "1.0.0",
  "sideEffects": false
}

例: 一部のファイルに副作用がある場合

[編集]
{
  "sideEffects": ["*.css"]
}

注意点

[編集]
  1. Dynamic Import(動的インポート) 動的インポート(import())は依存関係を動的に解析するため、Tree Shaking には向きません。
  2. デッドコードの明確化 未使用のコードが副作用を持つ場合、削除が難しくなります。そのため、関数やモジュールを小さな単位に分割することが重要です。
  3. ライブラリの対応状況 ライブラリが sideEffects フィールドを正しく設定していない場合、Tree Shaking の恩恵を受けられない可能性があります。

まとめ

[編集]

Tree Shaking は、コードの最適化において非常に強力な技術です。未使用のコードを削除することで、バンドルサイズを削減し、アプリケーションのパフォーマンスを向上させます。

効果的に Tree Shaking を活用するには、以下を心がけましょう:

  • ESM を使用し、明確なエクスポートを設計する。
  • バンドルツールの設定を最適化する。
  • 副作用の有無を正しく指定する。

これらの手法を組み合わせることで、モダンな JavaScript 開発における効率的なコード管理が可能になります。