JavaScript 最小化の仕組み
Terser はコードの抽象構文木(AST)に対して 4 つのステージで処理します。各ステージは独立しているため、他のステージを壊さずにオン・オフを切り替えられます。
- パース. Terser は JavaScript を AST にパースします。構文エラーはここで、原因となったトークンと行番号とともに表面化するため、変換が実行される前に本当の問題を発見できます。パーサーは最新の stage-4 プロポーザルまでのすべての標準 ECMAScript 構文を受け付けます。
- 圧縮. コンプレッサーは AST を走査し、意味を保存する多数の変換を適用します:定数畳み込み、デッドブランチ除去、短い純粋関数のインライン化、連続する
var宣言の縮約、等価な文形式の書き換え(if/elseの三項演算子化、比較チェーンの短縮、条件付き return の縮約)。すべての変換は原則として可逆で、コンプレッサーは観測可能な動作を変更しません。 - マングル. マングラーは各スコープ内のローカルバインディングを最短の一意な識別子(
a、b、c、…)に改名します。モジュール境界を越えられない名前だけが改名されるため、エクスポートされたバインディング、プロパティキー、グローバル参照は変更されません。この結果はいずれのステージよりも大きな単一のバイト削減をもたらします。 - レンダリング. Terser は変換された AST を、空白が縮約され文の区切りが文法上許容される最小限に削減された JavaScript 文字列として出力します。ライセンス保持トグルが
/*! … */ブロックを残さない限り、コメントは除去されます。ほとんどの CDN ライセンスではこれらのブロックの保持が要求されます。
JavaScript を最小化する理由
- ページ読み込みの高速化. 小さなスクリプトはより早くパース・実行されます。4G モバイル回線では 40% のバイト削減が Time to Interactive から実際の秒数を削り、これは Google の PageSpeed Insights が最も積極的に測定するメトリクスです。
- CDN エグレス費用の削減. CloudFront、Cloudflare、Fastly はギガバイト単位のエグレスを課金します。月間数百万ページビューにわたる 40% のスクリプト削減は、画像や CSS の作業よりも先に実際の節約として積み上がります。gzip や brotli の後でも計算は成り立ちます——最小化によって、コンプレッサーが本来エンコードしていたトークンが除去されるからです。
- このミニファイアはあなたのページを重くしません. Terser は非圧縮で約 1 MB あります。ほとんどのオンラインミニファイアはページ読み込み時にライブラリ全体を配信するため、自身の Lighthouse スコアを悪化させ、ユーザーが何か入力する前からページが重く感じられます。このページは Terser を遅延ロードし、「最小化」をクリックするかライブモードをオンにしたときだけ読み込みます——初回レンダリングがツール自身が達成を約束する Core Web Vitals のしきい値内に収まるようにです。
- Core Web Vitals への対応. Lighthouse と PageSpeed Insights は大きな JavaScript を Total Blocking Time 悪化の直接要因としてフラグを立てます。ベンダーライブラリとアプリケーションバンドルの最小化は、Lighthouse の「未使用 JavaScript を削減」および「重複モジュールを削除」監査で最も早い改善策です——通常、一度の削減で 10〜20 ポイント相当の改善が得られます。
主な用途
JavaScript の最小化は、モダンな Web プロジェクトのほぼすべてのステージに登場します。
- コミット前フック:個別のユーティリティスクリプトをコミット前に最小化することで、コミットされた成果物が本番対応済みになり、差分がロジックの変更を示し空白の乱れを含まなくなります。
- サードパーティウィジェットの監査:ベンダーの埋め込みスニペットを貼り付けて、すでに最小化済みかどうか、あるいは数百万ユーザーに配信する前にさらに縮小できるかを確認します。
- レガシースクリプトのクリーンアップ:ソースツリーに触れずに、現在のビルドパイプライン以前の古い jQuery プラグインや手書きスクリプトを圧縮します。
実践的な例
小さな関数を用意します:function add(firstNumber, secondNumber) { /* sums two numbers */ return firstNumber + secondNumber; } console.log(add(1, 2)); ——コメントを含む約 130 バイトです。マングルと圧縮の両方をオンにして上に貼り付けてください。出力は概ね function add(n,o){return n+o}console.log(add(1,2)); に短縮されます——約 55 バイト、58% の削減です。関数名 add は console.log 呼び出しで参照されているため残ります;パラメーター名 firstNumber と secondNumber は関数本体のローカル変数であるため 1 文字に短縮されます。マングルをオフにすると、空白の縮約とコメントの削除は維持しながら読みやすいパラメーター名を保持できます。
FAQ
これはブラウザーで動きますか?
はい。Terser は「最小化」をクリックするかライブモードを有効にした初回に遅延ロードされます——約 200 KB 圧縮済みがブラウザーキャッシュに入り、それ以降の追加ダウンロードはありません。あなたのコードはページを離れません。
名前マングリングとは何ですか?安全ですか?
マングリングはローカル変数をバイト節約のために 1 文字に改名します。改名がスコープ外に出ないため、自己完結型スクリプトと IIFE バンドルでは安全です。ラッパーなしでグローバルを名前で公開するスクリプト(例:window.myLib = …)では安全ではありません。確信が持てない場合はマングルをオフにしてください。
最小化後にコードが壊れたのはなぜですか?
よくある 3 つの原因:文字列で変数を参照する eval または with;元の識別子に依存する Function.name または arguments.callee の読み取り;改名された名前で公開されるグローバル。まずマングルをオフにして、改名か Compress の変換が原因かを切り分けてください。
モダンな構文(ES2020+)に対応していますか?
はい。ECMAScript ターゲットを ES2020 または Next に設定すると、Terser はオプショナルチェーン、Null 合体演算子、トップレベル await、論理代入演算子を保持します。ES5 に設定すると Terser は可能な範囲でダウンコンパイルしますが、完全なトランスパイラーではありません——ES5 では表現できない構文には Babel を使用してください。
Terser によるブラウザーサイドの JavaScript 最小化は、ビルドツールを追加せずに本番品質の出力を提供します。スクリプトを貼り付け、ECMAScript ターゲットを選択し、結果をコピーまたはダウンロードしてください。アップロードなし、アカウント不要、ビルドパイプライン不要。ミニファイア自体はあなたが実行を求めたときだけ読み込まれます——このページを開くコストは数キロバイトであり、1 メガバイトではありません。