次の方法で共有


ページの読み込み時間に対する拡張機能の影響を最小限に抑える

コンテンツ スクリプトは、拡張機能が Web ページに挿入する JavaScript ファイルであり、これらの Web ページのコンテキストで実行されます。 コンテンツ スクリプトを使用して、拡張機能は DOM から読み取りまたは変更することで、レンダリングされた Web ページにアクセスして変更できます。

ただし、コンテンツ スクリプトは、ページの読み込み時間を遅くするなどして、Web ページのパフォーマンスに大きな影響を与える可能性があります。 これは、ページの読み込み中にコンテンツ スクリプトで多数のコードが実行される場合に発生する可能性があります。

この記事では、ユーザーがアクセスする Web ページに対する拡張機能のパフォーマンスへの影響を最小限に抑えるのに役立つベスト プラクティスについて説明します。

拡張機能コンテンツ スクリプトをプロファイリングする

拡張機能のコンテンツ スクリプトのパフォーマンスをプロファイリングするには、次のセクションで説明するように、Microsoft Edge DevTools または Edge トレース ツールを使用します。

Microsoft Edge DevTools を使用してコンテンツ スクリプトをプロファイリングする

DevTools には、Web ページで使用されるコードを検査、デバッグ、プロファイリングするための一連の機能が用意されています。 DevTools を使用して、拡張機能のコードをプロファイリングすることもできます。

このセクションでは、DevTools の パフォーマンス ツールを使用して拡張機能のコンテンツ スクリプトをプロファイリングする方法について説明します。 パフォーマンス ツールの詳細については、「 パフォーマンス ツール の概要」を参照してください。

  1. DevTools を開くには、Web ページを右クリックし、[ 検査] を選択します。 または、 Ctrl + Shift + I (Windows、Linux) または Command + Option + I (macOS) を押します。 DevTools が開きます。

  2. DevTools の アクティビティ バーで、[ パフォーマンス (パフォーマンス ツール アイコン)] タブを選択します。そのタブが表示されない場合は、 その他のツール (その他のツール アイコン) >Performance を選択します。

  3. パフォーマンス プロファイルの記録を開始するには、[ 記録 ] (レコード アイコン) ボタンをクリックします。

  4. ページを再読み込みして、ページの読み込み時間に対応するプロファイル データをキャプチャし、ページの読み込みが完了したら、[ 停止 ] (停止アイコン) ボタンをクリックして記録を終了します。 DevTools には、記録されたパフォーマンス プロファイルが表示されます。

    DevTools パフォーマンス ツールに表示される記録されたパフォーマンス プロファイル

  5. コンテンツ スクリプトによって発生するパフォーマンス イベントを検索するには、Windows/Linux で Ctrl キーを押しながら F キーを押すか、macOS の 場合は Command + F キー を押します。 [ 検索 ] テキスト ボックスが パフォーマンス ツールの下部に表示されます。

  6. スクリプトの評価」と入力し、コンテンツ スクリプトによって発生するパフォーマンス イベントがパフォーマンス ツールによって強調表示されるまで Enter キーを押します。 [概要] パネルの [スクリプト] ラベルにコンテンツ スクリプトの名前が表示されたときに、適切なパフォーマンス イベントが見つかったことがわかります。

    ページの読み込み中に実行されている拡張機能のコンテンツ スクリプトによるスクリプトパフォーマンスの評価イベント

Edge トレース ツールを使用してコンテンツ スクリプトをプロファイリングする

edge://tracing URL で使用できる Edge トレース ツールは、拡張機能のパフォーマンスを詳細に分析できる強力なツールです。 このセクションでは、Edge トレース ツールを使用して、拡張機能がページの読み込み時間に与える影響を理解する方法について説明します。 Perfetto ツールに基づくこのトレース ツールの詳細については、「 Perfetto Tracing Docs」の 「Perfetto UI 」を参照してください。

  1. Edge トレース ツールを開くには、新しいタブまたはウィンドウを開き、[ edge://tracing] に移動します。 トレース UI が開きます。

  2. 新しいトレースを開始するには、ツールの左上隅にある [ 記録 ] ボタンをクリックします。 [ 新しいトレースの記録 ] ダイアログが開きます。

  3. [ 手動で設定を選択] オプション ボタンを選択します。 カテゴリの一覧が表示されます。

  4. 拡張機能のコンテンツ スクリプトのコンパイルと実行に関する詳細情報をキャプチャするには、次のすべてのカテゴリを選択します。

    • 拡張 機能
    • v8
    • devtools
    • devtools。タイムライン
  5. [ レコード ] ボタンをクリックします。 ダイアログが閉じられ、Edge トレース ツールによってトレースの記録が開始されます。

  6. 新しいタブを開き、拡張機能が影響する Web ページを読み込みます。 トレース ツールは、Web ページでの拡張機能のパフォーマンスへの影響に関するデータを収集します。

  7. エッジ トレース ツールが実行されているタブを開き、[ 停止 ] ボタンをクリックします。 ツールに新しいトレース情報が表示されます。

結果をフィルター処理する

Edge トレース ツールによって記録されるトレースは、ブラウザーと拡張機能に関する多くの情報を提供します。

拡張機能が影響を受けた Web ページに関連するもののみを表示するように情報をフィルター処理するには:

  1. [ edge://tracing ] ページで Shift キーを押しながら Esc キーを押して、[ ブラウザー タスク マネージャー ] ダイアログを開きます。

  2. [ ブラウザー タスク マネージャー ] ダイアログで、拡張機能が影響を受けた Web ページに対応するタブを検索し、[ プロセス ID ] 列の番号をメモします。 ダイアログを閉じます。

  3. Edge トレース ツールのツール バーで、[ プロセス] をクリックし、注目したプロセス ID に対応するチェック ボックスをオンにします。 他のすべてのチェック ボックスをオフにします。

  4. Edge トレース ツールの右上隅にある検索フィールドをクリックし、「 ScriptInjection::InjectJS」と入力し、下部のパネルで拡張機能に対応するイベントが強調表示されるまで Enter キーを 繰り返し押します。

    下部のパネルには、イベントの開始時刻と合計期間が表示されます。

    スクリプト インジェクション イベントを示す Edge トレース ツール

重要なイベントを探す

Web ページでの拡張機能のコンテンツ スクリプトのパフォーマンスへの影響の分析を続行するには、 ScriptInjection::InjectJS イベント内で次の重要なイベントを探します。

  • v8.compile - コンテンツ スクリプトのコンパイル時間を示します。
  • v8.run - コンパイル済みスクリプトの実行時間を示します。

拡張機能の機能に必要なコンテンツ スクリプト コードのみを追加する

拡張機能のコンテンツ スクリプトは、Web ページのコンテキストで実行されます。 コンテンツ スクリプトが Web ページに与える影響を最小限に抑えるには、コンテンツ スクリプトに、拡張機能が Web ページのコンテキストで実行する必要がある最小限のコードのみを追加してください。 コンテンツ スクリプトのコードを監査し、Microsoft Edge で実行するためにコンテンツ スクリプトで必要ないレガシ フレームワーク、ツール、ライブラリ、またはその他のコードを削除します。

遅延読み込みとコード分割の手法を使用して、コンテンツ スクリプトで実行されるコードの量を最小限に抑えることができます。

  • 遅延読み込みは 、ユーザーアクション、ページコンテンツ、または拡張ロジックに基づいて、必要なときにのみコードを読み込むプロセスです。

  • コード分割 は、コードを小さなチャンクまたはモジュールに分割するプロセスであり、個別またはオンデマンドで読み込むことができます。

拡張機能が十分に小さい場合は、コードを分割するためのビルド ツールは必要ありません。 拡張機能が大きく、コードの管理が複雑な場合は、ビルド ツールを使用してコードを小さなチャンクに分割します。 ビルド ツールを使用すると、必要に応じて読み込み可能な論理ユニットにコードを整理できます。 たとえば、webpack を使用して、コードを エントリ ポイント動的インポートに分割できます。

  • エントリ ポイントは、すべてのページ読み込み時に読み込まれます。

  • 動的インポートは、ユーザーが Web ページや拡張機能の UI と対話する場合など、必要に応じてのみ読み込まれます。

    // When the user clicks on the page.
    document.addEventListener("click", async () => {
      // Dynamically load the code that's needed to handle the click event.
      const module = await import("chunk.js");
      // Do something with the newly loaded module code.
    });
    

必要なページとフレームにのみコンテンツ スクリプトを読み込む

拡張機能は、ユーザーがアクセスするすべての Web ページで実行する必要がない場合があります。 Web ページの読み込み時に実行されるコードの量を減らすには、必要なページとフレームにのみコンテンツ スクリプトを読み込む拡張機能を構成します。

コンテンツ スクリプトが読み込まれるページとフレームを構成するには、content_scripts セクションの matches プロパティを使用して、拡張マニフェスト ファイルで URL パターンを定義します。 詳細については、Chrome 拡張機能のドキュメントの「コンテンツ スクリプトにスクリプトを挿入する」を参照してください。

また、 chrome.scripting 拡張機能 API を使用して、プログラムによってコンテンツ スクリプトを Web ページに挿入することもできます。 この API を使用すると、ユーザーのアクション、Web ページのコンテンツ、または拡張ロジックに基づいてコンテンツ スクリプトを挿入できます。 詳細については、Chrome 拡張機能のドキュメントの chrome.scripting に関するページを参照してください。

コンテンツ スクリプトを読み込む場所を構成する場合は、次のベスト プラクティスを使用します。

  • 拡張マニフェスト ファイルの matches プロパティと exclude_matches プロパティに可能な限り最も具体的な URL パターンを使用します。 たとえば、コンテンツ スクリプトを example.com ドメインの Web ページでのみ実行する必要がある場合は、"*://*/*" ではなく https://example.com/* を使用します。

  • コンテンツ スクリプトが最上位のフレームでのみ実行されるか、URL パターンに一致する Web ページの入れ子になったフレーム内でのみ実行されるかを制御するには、拡張マニフェスト ファイルの all_frames プロパティを使用します。 既定では、このプロパティは false に設定されています。つまり、コンテンツ スクリプトは最上位のフレームでのみ実行されます。 コンテンツ スクリプトが入れ子になったフレーム内の DOM にアクセスまたは変更する必要がある場合は、このプロパティを true に設定します。 all_framestrue に設定すると、Web ページで実行されるコードの量が増える点に注意してください。

必要な場合にのみコンテンツ スクリプトを読み込む

読み込まれ、各 Web ページで実行されるコードの量を減らし、メモリと CPU リソースを節約するには、すべてのページ読み込みではなく、必要に応じてコンテンツ スクリプトのみを読み込みます。

拡張機能マニフェスト ファイルにコンテンツ スクリプトを読み込むタイミングを構成する

拡張機能のコンテンツ スクリプトを読み込むタイミングを制御するには、拡張機能のマニフェスト ファイルで run_at プロパティを使用します。

既定では、このプロパティは document_idle 値に設定されています。つまり、ページの読み込みが完了し、DOM の準備ができたら、コンテンツ スクリプトが読み込まれ、実行されます。 これは、ほとんどのコンテンツ スクリプトに推奨される値です。 document_idle値は、コンテンツ スクリプトがページ読み込みプロセスに干渉しないようにします。

ページが完全に読み込まれる前にコンテンツ スクリプトを読み込んで実行するには、 document_start または document_end 値を使用します。 これらの値は、Web ページのレイアウトやスタイルの変更などの場合に便利ですが、ページ上の他のスクリプトでパフォーマンスの問題や互換性の問題が発生する可能性もあります。

実行時にプログラムによってコンテンツ スクリプトを読み込む

実行時にプログラムによってコンテンツ スクリプトを読み込むには、必要な場合にのみ、 chrome.scripting API を使用します。 chrome.scripting API を使用すると、コンテンツ スクリプトが読み込まれるタイミングと場所をより詳細に制御できます。

たとえば、 chrome.scripting API を使用してコンテンツ スクリプトを読み込むのは、拡張機能のボタンをクリックしたときや Web ページの一部をクリックしたときなど、ユーザーが Web ページや拡張機能 UI を操作した後だけです。

ユーザーが Web ページと対話するときに chrome.scripting API を使用する場合は、操作が行われるたびにコンテンツ スクリプトを繰り返し読み込む必要があるかどうかを慎重に検討してください。 コンテンツ スクリプトを頻繁に読み込みすぎると、ユーザー エクスペリエンスの問題やエラーが発生する可能性があります。

呼び出しまたは実行時間の長い同期タスクをブロックしないようにする

呼び出しと実行時間の長い同期タスクをブロックすると、Web ページの読み込みが遅くなったり、Web ページの他の側面が遅くなったり、UI の応答性に悪影響を与えたりする可能性があります。

呼び出しをブロックすることは、完了するまで他のコードの実行を妨げる JavaScript 操作です。 たとえば、 XMLHttpRequestlocalStorage、または chrome.storage.sync API (同期) を使用すると、Web ページで他のコードが実行されなくなります。

実行時間の長い同期タスク は、完了するまでに時間がかかる同期タスクであり、ブラウザーが実行中に他の Web ページ コードを実行できないようにします。 これには、複雑な計算、ループ、または文字列操作が含まれます。

可能な場合は、Fetch API、JavaScript Promises、Web Worker などの非同期または非ブロックのコードを使用します。 非同期コードまたは非ブロック コードを使用すると、Web ページを実行するブラウザー プロセスをブロックすることなく、タスクの完了を待っている間に他のコードを実行できます。

Web Worker を使用して複雑なコード ロジックを別のスレッドに移動することをお勧めしますが、CPU コア数が少ないデバイスや既にビジー状態のデバイスの速度が低下する可能性があることに注意してください。

Fetch API の使用例を次に示します。 データがフェッチされている間、ブラウザーはブロックされず、他のコードを実行できます。

// Asynchronously load data from a JSON file.
fetch("data.json")
  .then(response => response.json())
  .then(data => {
    // Do something with the data.
  });

データを非同期的に格納する

拡張機能にデータを格納するには、同期 API である localStorage API ではなく、chrome.storage.local API を使用します。 chrome.storage.local API は非同期であり、拡張機能が実行されている Web ページのパフォーマンスに影響を与えることなく、データをより効率的に格納および取得できます。 たとえば、 chrome.storage.local.get メソッドを使用して、以前に格納された値を取得し、その結果をコールバック関数で使用できます。

chrome.storage.local.get("key", result => {
  // Do something with the result.
});

メッセージを非同期的に送信する

コンテンツ スクリプトと拡張機能のバックグラウンド ページ、またはその他のコンテンツ スクリプトの間で通信するには、 chrome.runtime.sendMessage または chrome.tabs.sendMessage メソッドを使用します。 これらのメソッドは非同期および非ブロックであり、拡張機能のさまざまな部分間でメッセージを送受信できます。 Promise またはコールバックを使用して、メッセージの応答を処理できます。 たとえば、 chrome.runtime.sendMessage メソッドを使用してバックグラウンド ページにメッセージを送信し、返された Promise オブジェクトを使用して応答を処理できます。

chrome.runtime.sendMessage({type: 'request', data: 'some data'})
  .then(response => {
    // Do something with the response.
  });

メイン スレッドから集中的なタスクを実行する

Web Worker を使用して、ブラウザーが Web ページのレンダリングに使用するスレッドをブロックせずに、コンテンツ スクリプトで集中的なタスクを実行します。 Web Worker を使用すると、集中的なタスクを実行するコードは別のスレッドで実行されます。 Web Worker は、コンテンツ スクリプトとそれが実行されている Web ページのパフォーマンスと応答性を向上させることができます。

Web Worker を作成すると、デバイス上の新しいリソースを使用する新しいスレッドが作成されることに注意してください。 ローエンド デバイスでリソースを多く使用すると、パフォーマンスの問題が発生する可能性があります。

コンテンツ スクリプトと Web Worker の間で通信するには、 postMessage API と onmessage API を使用します。 たとえば、新しい Web Worker を作成してメッセージを送信するには、次のコードを使用します。

// Create a new Web Worker.
cons worker = new Worker('worker.js');

// Send a message to the Web Worker.
worker.postMessage({type: 'task', data: 'some data'});

Web Worker でメッセージを受信し、メッセージを送信するには:

// Listen to messages that are sent to the Web Worker.
onmessage = event => {
  const type = event.data.type;
  const data = event.data.data;

  // Do something with the type and data.
  // ...

  // Send a message back.
  postMessage({type: 'result', data: 'some result'});
};

関連項目

Chrome 拡張機能のドキュメント:

MDN: