ツリーシェイキング

バンドル時に未使用のコードを除去し、出力サイズを削減する最適化手法

ビルドパフォーマンス

ツリーシェイキングとは

ツリーシェイキング (Tree Shaking) は、バンドラー (esbuild, webpack, Rollup) がビルド時に未使用のコード (デッドコード) を除去し、出力サイズを削減する最適化手法である。ES Modules の静的構造を利用して、使われていない export を検出する。

仕組み

// utils.ts
export function add(a: number, b: number) { return a + b; }
export function multiply(a: number, b: number) { return a * b; }

// main.ts
import { add } from './utils';
console.log(add(1, 2));

// バンドル結果: multiply は含まれない (ツリーシェイキング)

ESM vs CommonJS

モジュール ツリーシェイキング 理由
ESM (import/export) ✅ 可能 静的解析可能
CommonJS (require) ❌ 不可 動的で解析不能
// ✅ ESM: ツリーシェイキング可能
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';

// ❌ CommonJS: ツリーシェイキング不可
const AWS = require('aws-sdk'); // SDK v2 全体がバンドルされる

AWS SDK v3 とツリーシェイキング

// ✅ SDK v3: サービスごとにインポート (ツリーシェイキング対応)
import { DynamoDBClient, GetItemCommand } from '@aws-sdk/client-dynamodb';
// → DynamoDB のクライアントのみバンドル

// ❌ SDK v2: 全サービスがバンドルされる
import AWS from 'aws-sdk';
// → S3, EC2, Lambda... 全サービスのコードが含まれる

Lambda でのバンドルサイズ

Metadata:
  BuildMethod: esbuild
  BuildProperties:
    Minify: true
    Target: es2022
    External: ['@aws-sdk/*']  # Lambda ランタイムに含まれる SDK は除外

esbuild でバンドルすると、ツリーシェイキング + ミニファイで Lambda のデプロイサイズを大幅に削減できる。

ツリーシェイキングが効かないケース

ケース 理由
副作用のあるモジュール import するだけで実行されるコード
CommonJS 動的で静的解析不能
eval() 動的なコード実行
barrel ファイル export * from で全てを再エクスポート

sideEffects フラグ

{
  "name": "my-library",
  "sideEffects": false
}

package.jsonsideEffects: false は、バンドラーに「このパッケージは副作用がない」と伝え、ツリーシェイキングを積極的に行わせる。

全体像を把握するには関連書籍も有用。

関連用語