「使用していないJavaScriptの削減」原因特定から改善方法を解説

「使用していないJavaScriptの削減」原因特定から改善方法を解説

Webページの表示速度を改善しようとすると、必ず目にするのが「使用していないJavaScriptの削減」という指摘です。

PageSpeed Insightsの診断項目は出るものの、「何が無駄なのか」「どこから手を付ければいいのか分からない」と感じる方も多いでしょう。

本記事では、その原因を正しく特定する方法から、実践的な改善手順までを分かりやすく解説します。

「使用していないJavaScriptの削減」とは

使用していないJavaScriptの削減」とは、PageSpeed Insightsの診断で指摘される改善項目の一つで、ページ表示に必要ない(そのページの読み込みや操作時に実行されない)JavaScriptコードを減らし、表示速度を改善する施策です。

JavaScriptは読み込み時にダウンロード・解析・コンパイル・評価が走るため、不要分が多いほど描画や操作応答が遅くなります。

PageSpeed InsightsでURLを分析すると「パフォーマンスの問題を診断する>インサイト」の箇所に表示されます。

また、上記の赤枠に削減できるサイズが表示され、数字が多いほど改善の余地があるということになります。

青枠が対象となるファイル名で、黄色枠がそれぞれのファイルの削減ができるサイズになります。

使用していない JavaScript を削除して、必要になるまでスクリプトの読み込みを遅らせると、ネットワークの通信量を減らすことができます。

といった内容が記載されていて、主に不要スクリプトの削除、遅延読み込み、コード分割などで対処していく必要があります。

何が“未使用”と判定されるのか

“未使用”と判定されるのは、ページ内で読み込まれているJavaScriptのうち、そのページの読み込みやユーザー操作の範囲では実行されない(使われない)コード部分です。

PageSpeed Insightsでは、こうした未使用コードを含むJSファイルを検出し、削減余地(削減できるバイト量)として提示します。

なお、判定の裏取りにはChrome DevToolsのカバレッジ を使い、実行された(使用)/実行されていない(未使用)の割合で確認します。

追って確認の方法も詳しく解説します。

使用していないJavaScriptで表示速度が落ちる理由

表示速度が落ちる主因は、ブラウザがページを描画する前後でJavaScriptを「ダウンロード→解析→コンパイル→評価(実行準備)」する必要があるためです。

未使用コードが多いと、この一連の処理に余計な時間とCPU負荷がかかり、描画開始が遅れたり、操作に反応できない時間(メインスレッドが塞がる)が増えます。

とくにJavaScriptが描画を妨げる(render-blocking)形だと、必要なDOM/CSSの処理より先にJS処理が割り込んで、体感速度が悪化します。

これらがレンダリングブロックの要因となり、LCPやFCPにも影響が出ます。

逆を返せば、これらをできる限り削減できればウェブサイトの表示速度は速くなります。

参考記事:レンダリングブロックしているリクエスト

削減の基本パターンは3つ

削減できるパターンは下記の3つとなります。

  1. 消す(本当に不要)
  2. 分ける(ページ/機能単位にコード分割)
  3. 後で読み込ませる(遅延読み込み・実行タイミング最適化)

消す方法について

そのページで使っていないタグ/プラグイン/ライブラリを停止・削除し、読み込み自体をなくします。

主にいらないJavaScriptを確認し削除する作業になります。

分けるについて

例えば1つの巨大なJavaScriptファイルで作成してしまっている場合などに、ページや機能単位にコード分割しすることをさします。

必要なタイミングで必要な分のファイルだけ読み込めるように調整する作業となります。

後で読み込ませるについて

初期表示に不要なJavaScriptはdefer等で遅延読み込みし、描画を優先します。

まず“消せるもの”→“分ける”→“後で読む”の順が最短です。

本当に直すべきかの判断基準と優先順位

本当に直すべきかは、PageSpeed Insightsで「指摘が出た」だけで判断せず、実際の体感速度と削減余地(KB)で決めていくことをお勧めします。

JavaScriptも必ず入れないとサイトが機能しない要素などもあるため、優先やバランスが大事になってきます。

おすすめの優先順位は下記を参考に判断してみてください。

  1. トップ流入やCVページで影響(重要度)が大きいもの
  2. 初期表示で読まれる大容量JS
  3. カバレッジで未使用率が高いもの(赤が多い)
  4. サードパーティ(計測/広告)
  5. 低頻度機能

PageSpeed Insightsの確認と見るべきポイント

下記画像の赤枠の全体の削減サイズと黄色枠の推定の削減サイズを確認し、大きいサイズのものから削減できるか検討してみましょう。

青い枠のファイル名を確認し、使用されているものかどうか、削減できる可能性があるかなどで着手を判断していくといいでしょう。

よくある原因のトップ5

特に下記のようなファイルはピックアップされることが多い要因となります。

  • 計測系(タグマネ/解析)
  • 広告・埋め込み
  • UIライブラリの一括読み込み
  • SPAの巨大バンドル
  • WordPressのプラグイン由来(機能は使ってないのに読み込んでいる)

計測系や広告タグに関しては、本当に必要なものかどうか?

カルーセルやスライダーなど、JavaScriptで作られたコンテンツは分割して最適なタイミングで読み込めそうか?

などが多く考えられます。

未使用JavaScriptの特定方法

「未使用JavaScript」は“削除していいJavaScript”とは限りません。

まずはPageSpeed Insightsで、未使用コードを含むJavaScriptファイル(削減可能KBつき)の候補リストを出します。(上記で説明した画像の青枠部分)

次にChrome DevToolsのカバレッジで実際の使用率(赤=未使用、青=使用)を計測し、対象ページでの操作も再現して裏取りします。

これで「本当に削る/遅延する/分割する」べきJavaScriptが安全に特定できます。

DevToolsのカバレッジで“本当に未使用”を確認する方法

Chromeで対象ページを開いたらDevToolsを起動し、メニューからカバレッジ(画像赤枠部分)を表示して記録を開始(画像黄色枠部分)します。

その状態でリロードし、スクロール・メニュー展開・モーダル表示など「そのページで実際にユーザーが行う操作」を一通り再現してください。(画像オレンジ枠の部分)

すると各JS/CSSの使用率(未使用量)が可視化され、未使用割合が大きいファイルから優先的に削減対象を絞り込めます。(画像青枠部分)

カバレッジの結果は、赤=未使用灰色=使用の目安です。(画像青枠部分)

優先度は「赤の割合が大きい」だけでなく

  1. 初期表示で読み込まれている
  2. ファイル容量(合計バイト数)が大きい
  3. 未使用バイト(使用してないないバイト数)が多い

これらの優先度で着手していくことをお勧めします。

例えば下記の画像のケースであれば、黄色枠で囲っている部分のファイルが合計バイト数も使用していないバイト数も多く、ファイルの99.8%は使われていないということがわかります。

こういったファイルは優先的に確認していきましょう。

まずは“重くて、ほぼ使ってないJS”を潰すのが最短です。

また、下記画像のようにファイル名をクリックすると(画像黄色枠部分)、上部にファイルの中身が表示されますが、青枠の赤い部分は使用されていない状態のソースというのもわかります。

カバレッジを使いながら使用されていないJavaScriptのファイルやソースを探していきましょう。

未使用に見えるのに消すと壊れるケース

未使用に見えるのに消すと壊れる典型は、「計測時に実行されていないだけ」のJSです。

たとえば

  1. クリック・スクロール・ホバー後に初めて動くUI(モーダル、アコーディオン等)
  2. 特定条件でだけ発火する処理(ログイン後、フォーム送信後、ABテスト、地域/デバイス判定)
  3. 表示外コンテンツの遅延ロード(無限スクロール、下部CTA)

などは、カバレッジでは赤が多く見えても実運用で必要です。

削除前に“想定ユーザー行動”を一通り再現して確認します。

もし間違えで削除してしまったことも考えて、削除する前にバックアップなども取っておきましょう。

「使用していないJavaScriptの削減」の改善策

ここまでで、カバレッジで使用されていないJavaScriptを探す方法を紹介してきました。

探し方がわかったら、次は具体的な改善策をご紹介していきます。

主にやることとしては下記になります。

  1. 不要なスクリプトを削除・停止
  2. 初期表示に不要なJavaScriptは読み込みを遅らせる
  3. 巨大バンドルはコード分割

下記に詳しく解説していきます。

不要スクリプトの削除または停止

不要スクリプトの削除・停止は「そもそも読み込まない」状態を作れるため、最も効果が出やすい改善策です。

まずは、説明した通りカバレッジで使用されていないファイルや使用されていないスクリプトを特定しましょう。

削除のポイントを下記にまとめていきます。

ポイント①:未使用の計測タグがないか

広告タグ、アナリティクス、ヒートマップ等、重複していたり未使用のタグがないかを確認してみましょう。

重複のものは必要な分だけ残して削除します。

未使用のものも削除しておきましょう。

GTMに設置しているタグであれば停止することで対応することも可能です。

ポイント②:未使用の埋め込みコンテンツがないか

チャット、SNS、地図、動画などの埋め込みタグなど、導入しただけで全ページに重いJSを読み込み、実際には使われていないケースが多いのが特徴です。

カバレッジで対象ページを計測すると、該当スクリプトの未使用(赤)が目立つことがあります。

不要と判断できたら、埋め込みコード/タグマネ/プラグインから撤去して「読み込み自体をゼロ」にします。

読み込み・解析の負担が消えるため、未使用JavaScript削減の中でも効果が出やすい施策です。

ポイント③:WordPressの場合、プラグインの確認

WordPressではプラグインが入っているだけで、全ページ共通でJS/CSSを読み込むケースが多く、結果として「使用していないJavaScriptの削減」に引っかかりやすくなります。

まず不要なプラグインは停止・削除し、残すものは「お問い合わせページだけ」「記事ページだけ」など必要なページでのみ読み込む設定に変更します。

対象の特定はDevToolsのカバレッジで行い、未使用(赤)が多いファイルから見直すと効率的です

ポイント④:テーマや共通JavaScriptに残っている旧機能コードを削る

テーマや共通JavaScriptに残っている旧機能コードは、現在のページでは使っていなくても“全ページ共通”で読み込まれ続けるため、「使用していないJavaScriptの削減」の原因になりがちです。

まずDevToolsのカバレッジで計測し、未使用(赤)が多い処理やファイルを特定します。

その上で、削除済み機能(旧スライダー、旧追従バナー、古い計測イベント等)のコードをテーマ/共通バンドルから削る、または条件分岐して必要ページだけで読み込むよう整理します。

反映後は主要導線の操作テストで破壊的変更がないか確認します。

初期表示に不要なJavaScriptの読み込みを遅らせる

遅延読み込みとは、ファーストビュー表示に直接関係しないJavaScript(チャット、SNS埋め込み、分析タグ、下部コンテンツの動作など)を、初期表示のタイミングでは読み込まず、後から必要になった時点で読み込む最適化です。

JavaScriptは読み込み時に解析・評価の負荷がかかるため、初期に不要なJSを後回しにすると描画を邪魔しにくくなり、体感速度や指標改善につながります。

defer / asyncを使った具体的な改善方法

deferは、HTML解析を止めずにJavaScriptを取得し、DOM構築後に順序を保って実行される方法です。(多くのケースで第一候補)

下記のソース例を参考に導入してみましょう。

<script src="/assets/app.js" defer></script>

asyncは、取得でき次第すぐ実行する方法です。(順序が崩れるので依存が少ない計測系向き)

下記ソース例を参考にしてみてください。

<script src="https://example.com/tag.js" async></script>

コード分割の実施

コード分割は、1つに固まった巨大なJavaScriptバンドルを、ページや機能単位の「小さなチャンク」に分け、必要になったタイミングでだけ読み込む最適化です。

トップページでは不要な管理画面用コード、特定ページでしか使わないUI部品などを初期配信から外せるため、ダウンロード量と解析・評価コストを減らし、表示速度を改善できます。

動的importで「使うときに読む」を作る方法

動的importで「使うときに読む」を作るとは、import()(非同期のimport文)をコード分割の境界(split point)として設定し、必要な機能のJavaScriptだけを後から別チャンクとして読み込む手法です。

たとえば「ボタンを押したとき」「該当ページに遷移したとき」「特定UIを開いたとき」など、利用が確定したタイミングまで読み込み・実行を遅らせられるため、初期ロードのJS量と実行コストを減らせます。

①「遅延したい処理」を別ファイルに切り出す

例:モーダル(重いUI)を初期表示で使わないなら、モーダル処理を modal.js に寄せます

// modal.js(遅延ロードされる側)
export function openModal() {
  // ここにモーダル表示の処理
}

②初期ロード側のimportを、動的import()に置き換える

const module = await import('./modal.js');
module.openModal();

import()はPromiseを返すので、awaitまたは.then()で受けます。

③「使うとき」に読み込むトリガー(イベント)を決めて実装する

動的importで「使うとき」に読み込むには、読み込みのトリガー(クリック・スクロール・表示など)を先に決めて、そのイベント内でimport()を呼ぶのがポイントです。

トリガーのルールはサイトやコンテンツによって変わるので、下記を参考にしてみてください。

  • パターンA:クリックしたら読み込む(最も安全)
  • パターンB:初回表示で読み込む(「遅延」にはなるが効果は弱め)
  • パターンC:要素が画面に入ったら読み込む(下部コンテンツ向け)

webpackも、ユーザー操作が起きた時点で初めてモジュールを読み込む(クリックでimport())例を示しています。

また、Dynamic Importはコード分割の「分割点(split point)」として扱われ、必要な時だけ別バンドルを読み込める前提になります。

バンドラ最適化

バンドラ最適化とは、webpack/rollup等のビルド工程で、未使用コード(dead code)を除去し、配信するJSを最小化する取り組みです。

Productionビルドでは、使われない関数・exportを削る「Dead Code Elimination」を行い、不要なコードをブラウザに送らないことで「使用していないJavaScriptの削減」改善に直結します。

①「本番ビルド(production)」でビルドする

「本番ビルド(production)」でビルドする手順は、使っているフレームワーク/ビルドツールごとにコマンドが決まっています

webpackの場合で解説していきます。

手順A:webpack.config.js に mode: 'production' を設定

// webpack.config.js
module.exports = {
  mode: 'production',
};

productionでは最適化プラグイン(例:Terser)が有効になる、と公式に説明されています。

手順B:CLIでproduction指定してビルド(設定を書き換えたくない場合)

webpack --mode=production

CLI引数でmodeを渡せることも公式に記載があります。

②ES Modules(import/export)で書く・依存もESM版を使う

ES Modules(import/export)で書くのは、バンドラが静的解析で「使っていないコード」を判定し、ツリーシェイキング(Dead Code Elimination)を効かせるためです。

CommonJS(require)だと解析しづらく、未使用コードが残りやすい傾向があります。

ツリーシェイキングはES2015のimport/exportの静的構造に依存します。

自分のコードをESMに統一する

置き換え例

  • const x = require('x') → import x from 'x'
  • module.exports = ... → export default ... / export const ...

ツリーシェイキングはimport/exportを前提にして、未使用exportを落とせる設計です。

依存ライブラリを「ESM版が使える形」で読み込む

依存ライブラリはESM版(import/export対応)を使える形で読み込み、未使用部分をツリーシェイクで落とせる状態にします。

requireや“丸ごとimport”は避け、必要な機能だけをESMでimportします。

ツリーシェイキングはimport/exportに依存します。

webpackの例でも、使っていないexport(例:square)は「死んだコード」として扱われ、設定次第で削れる前提で説明されています。

webpackなら sideEffects の設定で“丸ごと削除”を許可する

webpackのsideEffects設定は、「副作用(importしただけで何かが起きる)を持たないファイルは、使っていなければ丸ごとバンドルから外してOK」というヒントをwebpackに与える仕組みです。

usedExportsより強力で、未使用なら“ファイル単位/依存ツリー単位”で削除できるため、未使用JavaScript削減に効きます。

設定はpackage.jsonのsideEffectsで行います。

③動的import(遅延ロード)でも“未使用export”を落とす工夫をする

動的importは分割に有効ですが、動的に取得したモジュールのexportは解析が難しいケースがあります。

テストでも、動的importしたモジュール内の未使用関数が残る可能性が示されています。

webpackの場合は、使うexportを明示して削除を効かせる方法が提示されています。

具体例

const { logCaps } = await import('./utils.js') のような分割代入だと削除が効かないことがあるため、webpackでは次のように webpackExports で利用exportを指定します。

const { logCaps } = await import(/* webpackExports: "logCaps" */ './utils.js');

④「まとめimport」をやめて、必要なものだけをimportする

まとめimport(barrel)でライブラリを丸ごと読み込むと、未使用コードまで依存関係に巻き込まれ、tree-shakingが効きにくくバンドルが肥大化します。

必要な関数・コンポーネントを個別importにすると、参照範囲が狭まり不要コードが落ちやすくなり、初期表示とビルド成果物を軽量化できます。

下記のような内容を改善していきましょう。

  • barrel(index.ts)経由を減らし、直接importする
  • UI/ユーティリティは“入口”ではなくサブパスimportを検討(提供されている場合)
  • export * の多用を避け、必要なexportだけ明示(依存の連鎖を抑える)
  • 副作用のある初期化(登録・extend・global CSS)を分離し、必要箇所で実行する
  • まずバンドル解析で“重い犯人”を特定し、上位から順に置換(最短で効果が出る)

改善できたかの検証方法

改善できたかは、同条件で再計測→差分確認で判断します。

PageSpeed InsightsとDevToolsの両方を使って検証すると確実です。

下記に検証方法を解説していきます。

PageSpeed Insightsスコアより“指標”を見る

まず、前提として修正する前の数値を計測しておきます。

下記の計測ポイントを参考に修正後の数値が減っているかどうかを確認します。

計測のポイント

上記の画像を元にポイントを解説します。

  • 削減サイズの数値が減っているか?(赤枠)
  • 対象のファイル(青枠)
  • 各ファイルの削減サイズ(オレンジ枠)

ページ全体で削減されているかを確認したい場合は、赤枠を確認。

各ファイルで変化をみたい場合は青枠とオレンジ枠を確認して変化を確認します。

DevToolsのカバレッジで確認

DevToolsも同様に修正する前の数値を計測しておきます。

特に確認しておきたいポイントとしては「使用していないバイト」の列のバイト数や%の割合を確認しておきましょう。

うまく削減ができている場合は、バイト数と割合が下がります。

「使用していないJavaScriptの削減」まとめ

「使用していないJavaScriptの削減」の具体的な作業の方法などを解説してきました。

ページで実行されないJS(未使用コード)を減らし、転送量と解析・実行コストを下げてサイト改善を頑張って進めていきましょう。

記事を書いた人

井上寛生

井上寛生

LandingHub 執行役員 / 事業責任者 / 技術責任者

大学院では情報工学を専攻し、修了後に株式会社TeNへ新卒入社。当時は社内唯一のエンジニアながら、開発部門をゼロから立ち上げ、採用・育成を一手に担い、全員が未経験からスタートした精鋭エンジニアチームを組成。2021 年にはWEBサイト高速化プラットフォーム「LandingHub」を立ち上げ、プロダクトオーナー兼事業責任者として企画・開発・グロースを牽引。現在は執行役員として、会社の技術戦略と事業成長の双方をリードしている。
コラム一覧に戻る