コードを最適化してもサイトの読み込みが遅い場合は、サードパーティのスクリプトが原因である可能性があります。
サードパーティ スクリプトは、ウェブをより動的でインタラクティブ、相互接続されたものにするさまざまな便利な機能を提供します。中には、ウェブサイトの機能や収益源にとって重要なものもあるかもしれません。しかし、これらを使用すると、次のようなリスクがあります。
- サイトのパフォーマンスが低下する可能性があります。
- プライバシーやセキュリティの問題を引き起こす可能性があります。
- 予測不可能な場合があり、その動作が意図しない結果をもたらす可能性があります。
理想的には、サードパーティ スクリプトがサイトのクリティカル レンダリング パスに影響を与えないようにする必要があります。このガイドでは、サードパーティの JavaScript の読み込みに関連する問題を見つけて修正し、ユーザーへのリスクを最小限に抑える方法について説明します。
サードパーティ スクリプトとは
サードパーティの JavaScript とは、サードパーティ ベンダーから直接任意のサイトに埋め込むことができるスクリプトを指します。次に例を示します。
ソーシャル共有ボタン(Facebook、X、LinkedIn、Mastodon)
動画プレーヤーの埋め込み(YouTube、Vimeo)
広告 iframe
分析と指標のスクリプト
テスト用の A/B テスト スクリプト
ヘルパー ライブラリ(日付の書式設定、アニメーション、関数ライブラリなど)
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/mo8thg5XGV0"
frameborder="0"
allow="autoplay; encrypted-media"
allowfullscreen
>
</iframe>
残念ながら、サードパーティのスクリプトを埋め込むということは、ページの読み込みを遅くしないように、スクリプトが迅速に実行されることを期待することになります。サードパーティ スクリプトは、サイト所有者の管理外のリソースが原因でパフォーマンスが低下する一般的な原因です。これには、次の問題が含まれます。
複数のサーバーに大量のネットワーク リクエストを送信している。サイトで処理する必要があるリクエストが多いほど、読み込みに時間がかかる可能性があります。
過剰な JavaScript を送信して、メインスレッドをビジー状態にしている。JavaScript が多すぎると、DOM の構築がブロックされ、ページのレンダリングが遅れる可能性があります。CPU 負荷の高いスクリプトの解析と実行は、ユーザー インタラクションを遅らせ、バッテリーを消耗させる可能性があります。
最適化されていない大きな画像ファイルや動画を送信すると、データが消費され、ユーザーに費用がかかる可能性があります。
ページがスクリプトを注意せずに読み込むと、単一障害点(SPOF)として機能する可能性があるセキュリティの問題。
HTTP キャッシュが不十分なため、ブラウザがリソースを取得するために送信するネットワーク リクエストが増加する。
サーバー圧縮が不十分な場合、リソースの読み込みが遅くなります。
処理が完了するまでコンテンツの表示をブロックする。これは、非同期 A/B テスト スクリプトにも当てはまります。
document.write() など、ユーザー エクスペリエンスを損なうことがわかっているレガシー API の使用。
DOM 要素が多すぎる、または CSS セレクタのコストが高い。
複数のサードパーティの埋め込みを含めると、複数のフレームワークとライブラリが複数回取り込まれ、リソースが無駄になり、既存のパフォーマンスの問題が悪化する可能性があります。
サードパーティのスクリプトでは、埋め込み手法がよく使用されます。この手法では、埋め込みで async または defer が使用されている場合でも、サーバーの応答が遅いと window.onload がブロックされることがあります。
サードパーティ スクリプトの問題を修正できるかどうかは、サイトと、サードパーティ コードの読み込み方法を構成する能力によって異なります。幸いなことに、サードパーティのリソースに関する問題を見つけて修正するためのソリューションやツールは多数存在します。
ページ上のサードパーティ スクリプトを特定するにはどうすればよいですか?
サイト上のサードパーティ スクリプトを特定し、パフォーマンスへの影響を判断することが、最適化の第一歩です。Chrome DevTools、PageSpeed Insights、WebPageTest などの無料のウェブ速度テストツールを使用して、コストの高いスクリプトを特定することをおすすめします。これらのツールは、サイトで使用されているサードパーティ スクリプトの数や、実行に最も時間がかかるスクリプトを特定できる、豊富な診断情報を表示します。
WebPageTest のウォーターフォール ビューでは、サードパーティ スクリプトの過剰な使用による影響をハイライト表示できます。Tags Gone Wild の次の画像は、トラッキング スクリプトやマーケティング スクリプトとは対照的に、サイトのメイン コンテンツを読み込むために必要なネットワーク リクエストの図の例を示しています。
WebPageTest のドメインの内訳は、サードパーティのオリジンから取得されるコンテンツの量を可視化する際にも役立ちます。合計バイト数とリクエスト数の両方で内訳が表示されます。
サードパーティ スクリプトがページに及ぼす影響を測定するにはどうすればよいですか?
問題の原因となっているスクリプトを見つけたら、そのスクリプトの動作を調べ、サイトの機能に必要かどうかを判断します。必要に応じて、A/B テストを実施して、認識される価値と、主要なユーザー エンゲージメント指標またはパフォーマンス指標への影響のバランスを取ります。
Lighthouse の起動時間監査
Lighthouse の JavaScript 起動時間監査では、スクリプトの解析、コンパイル、評価に時間がかかるスクリプトがハイライト表示されます。これにより、CPU 使用率の高いサードパーティ スクリプトを特定できます。
Lighthouse ネットワーク ペイロード監査
Lighthouse のネットワーク ペイロード監査では、ページの読み込み時間を遅くし、ユーザーが想定以上にモバイルデータを使用する原因となるサードパーティのネットワーク リクエストを含む、ネットワーク リクエストを特定します。
Chrome DevTools のネットワーク リクエストのブロック
Chrome DevTools を使用すると、指定したスクリプト、スタイルシート、その他のリソースが利用できない場合のページの動作を確認できます。これは、ネットワーク リクエストのブロックで行います。この機能は、ページから個々のサードパーティ リソースを削除した場合の影響を測定するのに役立ちます。
リクエストのブロックを有効にするには、[ネットワーク] パネルでリクエストを右クリックし、[リクエスト URL をブロック] を選択します。DevTools ドロワーにリクエスト ブロックタブが表示され、ブロックされたリクエストを管理できます。
Chrome DevTools の [Performance] パネル
Chrome DevTools のパフォーマンス パネルは、ページのウェブ パフォーマンスに関する問題を特定するのに役立ちます。
- [録画] をクリックします。
- ページを読み込みます。DevTools には、サイトの読み込み時間の内訳を示すウォーターフォール図が表示されます。
- [Performance] パネルの下部にある [Bottom-up] に移動します。
- [Group by product] をクリックし、ページのサードパーティ スクリプトを読み込み時間で並べ替えます。
Chrome DevTools を使用してページ読み込みのパフォーマンスを分析する方法については、ランタイム パフォーマンスの分析を始めるをご覧ください。
サードパーティ スクリプトの影響を測定するための推奨ワークフローは次のとおりです。
- [ネットワーク] パネルを使用して、ページの読み込みにかかる時間を測定します。
- 実際の状況をエミュレートするには、ネットワーク スロットリングと CPU スロットリングを有効にすることをおすすめします。ユーザーが、ラボ環境で負荷の高いスクリプトの影響を軽減する高速なネットワーク接続やデスクトップ ハードウェアを使用している可能性は低いです。
- 問題の原因となっているサードパーティ スクリプトの URL またはドメインをブロックします(コストの高いスクリプトを特定する方法については、Chrome DevTools の [Performance] パネルをご覧ください)。
- ページを再読み込みして、読み込み時間を再度測定します。
- より正確なデータを得るには、読み込み時間を少なくとも 3 回測定することをおすすめします。これは、一部のサードパーティ スクリプトがページ読み込みごとに異なるリソースを取得するためです。これを支援するため、DevTools のパフォーマンス パネルは複数の録画をサポートしています。
WebPageTest でサードパーティ スクリプトの影響を測定する
WebPageTest では、[Advanced Settings] > [Block] で、個々のリクエストの読み込みをブロックして、その影響を測定できます。この機能を使用して、広告ドメインなど、ブロックするドメインのリストを指定します。
この機能を使用するには、次のワークフローをおすすめします。
- サードパーティをブロックせずにページをテストします。
- 一部のサードパーティをブロックしてテストを繰り返します。
- [Test History] から 2 つの結果を選択します。
- [比較] をクリックします。
次の画像は、WebPageTest のフィルムストリップ機能で、アクティブなサードパーティ リソースがあるページとないページの読み込みシーケンスを比較したものです。個々のサードパーティ オリジンのテストでこのチェックを行い、ページのパフォーマンスに最も影響を与えるドメインを特定することをおすすめします。
WebPageTest では、DNS レベルで動作する 2 つのコマンドを使用してドメインをブロックすることもできます。
blockDomainsは、ブロックするドメインのリストを取得します。- blockDomainsExcept は、ドメインのリストを取得し、リストにないものをブロックします。
WebPageTest には、単一障害点(SPOF)タブもあり、リソースの読み込みのタイムアウトや完全な失敗をシミュレートできます。ドメイン ブロックとは異なり、SPOF はゆっくりとタイムアウトします。これは、サードパーティ サービスが高負荷状態にある場合や一時的に利用できない場合に、ページの動作をテストするのに役立ちます。
長いタスクを使用してコストの高い iframe を検出する
サードパーティの iframe 内のスクリプトの実行に時間がかかると、メインスレッドがブロックされ、他のタスクが遅れる可能性があります。このような長いタスクは、イベント ハンドラの動作を遅くしたり、フレームをドロップしたりして、ユーザー エクスペリエンスを低下させる可能性があります。
リアルユーザー モニタリング(RUM)で長いタスクを検出するには、JavaScript の PerformanceObserver API を使用して longtask エントリを監視します。これらのエントリには、長いタスクの原因となったフレーム コンテキストを特定するために使用できるアトリビューション プロパティが含まれています。
次のコードは、longtask エントリをコンソールにログ出力します。これには、「高負荷」の iframe のエントリも含まれます。
<script>
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Attribution entry including "containerSrc":"https://example.com"
console.log(JSON.stringify(entry.attribution));
}
});
observer.observe({entryTypes: ['longtask']});
</script>
<!-- Imagine this is an iframe with expensive long tasks -->
<iframe src="https://example.com"></iframe>
長いタスクのモニタリングの詳細については、ユーザー中心のパフォーマンス指標をご覧ください。
サードパーティ スクリプトを効率的に読み込むにはどうすればよいですか?
サードパーティ スクリプトが原因でページの読み込みが遅くなっている場合は、パフォーマンスを改善するためのいくつかの方法があります。
async属性またはdefer属性を使用してスクリプトを読み込み、ドキュメントの解析がブロックされないようにする。- サードパーティのサーバーが遅い場合は、スクリプトのセルフホスティングを検討する。
- サイトに明確な価値をもたらさない場合は、スクリプトを削除します。
<link rel=preconnect>や<link rel=dns-prefetch>などのリソースヒントを使用して、サードパーティ スクリプトをホストしているドメインの DNS ルックアップを実行します。
async または defer を使用します。
JavaScript の実行はパーサーをブロックします。ブラウザは、スクリプトを検出すると、DOM の構築を一時停止し、スクリプトを JavaScript エンジンに渡して、スクリプトを実行してから DOM の構築を続行する必要があります。
async 属性と defer 属性は、この動作を次のように変更します。
asyncを指定すると、ブラウザは HTML ドキュメントの解析を続けながら、スクリプトを非同期でダウンロードします。スクリプトのダウンロードが完了すると、スクリプトの実行中に解析がブロックされます。deferを指定すると、ブラウザは HTML ドキュメントの解析を続けながら、スクリプトを非同期でダウンロードします。その後、ドキュメントの解析が完了するまでスクリプトの実行を待機します。
スクリプトがクリティカル レンダリング パスに必要でない限り、サードパーティ スクリプトには常に async または defer を使用します。一部の分析スクリプトなど、読み込みプロセスの早い段階でスクリプトを実行することが重要な場合は、async を使用します。defer は、ユーザーが最初に目にする部分よりも下でレンダリングされる動画など、重要度の低いリソースに使用します。
パフォーマンスを重視する場合は、ページの重要なコンテンツが読み込まれるまで、非同期スクリプトの追加を待つことをおすすめします。jQuery などの重要なライブラリに async を使用することはおすすめしません。
一部のスクリプト(特にサイトの重要な部分を構成するスクリプト)は、async や defer を使用せずに読み込む必要があります。これには、サイトが機能するために不可欠な UI ライブラリやコンテンツ配信ネットワーク(CDN)フレームワークが含まれます。
他のスクリプトは、非同期で読み込まれると機能しません。使用しているスクリプトのドキュメントを確認し、非同期で読み込めないスクリプトを、非同期で読み込める代替スクリプトに置き換えます。サードパーティによっては、非同期でも同様に動作するにもかかわらず、スクリプトを同期的に実行することを推奨している場合があることに注意してください。
async ですべての問題が解決するわけではありません。ページに多数のスクリプト(広告目的のトラッキング スクリプトなど)が含まれている場合、非同期で読み込んでも、ページの読み込み速度の低下を防ぐことはできません。
リソースヒントを使用して接続設定時間を短縮する
サードパーティのオリジンへの接続を確立するには、特に低速なネットワークでは、DNS ルックアップやリダイレクトなど、ネットワーク リクエストに複数の複雑なコンポーネントが含まれているため、時間がかかることがあります。 などのリソースヒントを使用すると、ページ読み込みプロセスの早い段階でサードパーティ スクリプトをホストするドメインの DNS ルックアップを実行できるため、残りのネットワーク リクエストをより迅速に処理できます。
<link rel="dns-prefetch" href="http://example.com" />
接続先のサードパーティ ドメインが HTTPS を使用している場合は、 を使用することもできます。これは、DNS ルックアップと TCP ラウンドトリップの解決、TLS ネゴシエーションの処理の両方を行います。これらの他のステップは、SSL 証明書の検証を伴うため、非常に時間がかかることがあります。そのため、事前接続により読み込み時間を大幅に短縮できます。
<link rel="preconnect" href="https://cdn.example.com" />
iframe を使用した「サンドボックス」スクリプト
サードパーティ スクリプトを iframe に直接読み込むと、メインページの実行はブロックされません。AMP では、このアプローチを使用して JavaScript をクリティカル パスから除外しています。この方法でも onload イベントはブロックされるため、重要な機能を onload にアタッチしないようにしてください。
Chrome は、権限ポリシー(旧称: 機能ポリシー)もサポートしています。これは、デベロッパーが特定のブラウザ機能へのアクセスを選択的に無効にできるようにする一連のポリシーです。これを使用すると、第三者のコンテンツがサイトに望ましくない動作を導入するのを防ぐことができます。
サードパーティ スクリプトをセルフホストする
DNS 時間の短縮や HTTP キャッシュ ヘッダーの改善など、重要なスクリプトの読み込み方法をより細かく制御したい場合は、自分でホストすることもできます。
ただし、セルフホスティングには、特にスクリプトの更新に関して独自の問題が伴います。セルフホスト スクリプトでは、API の変更やセキュリティ修正の自動更新が行われません。そのため、スクリプトを手動で更新するまで、収益の損失やセキュリティの問題が発生する可能性があります。
別の方法として、Service Worker を使用してサードパーティ スクリプトをキャッシュに保存し、ネットワークからスクリプトを取得する頻度をより細かく制御することもできます。また、サービス ワーカーを使用して、ページが重要なユーザー モーメントに到達するまで、重要でないサードパーティのリクエストをスロットリングする読み込み戦略を作成することもできます。
ユーザーの小規模なサンプルで A/B テストを実施する
A/B テスト(スプリット テスト)は、2 つのバージョンのページをテストして、ユーザー エクスペリエンスと行動を分析する手法です。ウェブサイトのトラフィックのさまざまなサンプルでページのバージョンを利用できるようにし、どのバージョンがより高いコンバージョン率を提供するかを分析から判断します。
ただし、A/B テストは、どのテストを有効にするかを決定するためにレンダリングを遅らせるように設計されています。JavaScript は、ユーザーが A/B テストのテストに属しているかどうかを確認し、正しいバリエーションを有効にするためによく使用されます。このプロセスにより、テストに参加していないユーザーのエクスペリエンスも低下する可能性があります。
ページのレンダリングを高速化するには、A/B テスト スクリプトをユーザーベースのより小さなサンプルに送信し、表示するページのバージョンを決定するコードをサーバーサイドで実行することをおすすめします。
サードパーティ リソースの遅延読み込みを行う
広告や動画などの埋め込みサードパーティ リソースは、適切に構築されていないと、Page Speed を低下させる主な原因となる可能性があります。遅延読み込みを使用すると、必要な場合にのみ埋め込みリソースを読み込むことができます。たとえば、ユーザーがページをスクロールしてフッターが表示されるまで、フッターの広告の配信を待機できます。また、メインページのコンテンツが読み込まれた後、ユーザーがページを操作する前に、第三者のコンテンツを遅延読み込みすることもできます。
リソースの遅延読み込みを行う際は注意が必要です。多くの場合、JavaScript コードが関与するため、ネットワーク接続が不安定な場合に影響を受ける可能性があります。
DoubleClick の公式ドキュメントには、広告を遅延読み込みする方法に関するガイダンスが記載されています。
Intersection Observer を使用した効率的な遅延読み込み
これまで、遅延読み込みのために要素がビューポートに表示されているかどうかを検出する方法は、エラーが発生しやすく、ブラウザの速度が低下することがよくありました。このような非効率的な方法では、多くの場合、scroll イベントまたは resize イベントをリッスンし、getBoundingClientRect() などの DOM API を使用して、ビューポートを基準とした要素の位置を計算します。
IntersectionObserver は、監視対象の要素がブラウザのビューポートに出入りするタイミングをページ所有者が効率的に検出できるようにするブラウザ API です。LazySizes には、IntersectionObserver のオプション サポートもあります。
分析の遅延読み込み
アナリティクス スクリプトの読み込みを遅らせすぎると、貴重なアナリティクス データが失われる可能性があります。幸いなことに、初期のページ読み込みデータを保持しながら、分析を遅延初期化するための戦略があります。
Phil Walton のブログ投稿 The Google Analytics Setup I Use on Every Site I Build では、Google アナリティクス向けのそのような戦略の 1 つが紹介されています。
サードパーティ スクリプトを安全に読み込む
このセクションでは、サードパーティ スクリプトをできるだけ安全に読み込むためのガイダンスを提供します。
document.write() を避ける
サードパーティ スクリプト(特に古いサービスのもの)では、スクリプトの挿入と読み込みに document.write() が使用されることがあります。これは、document.write() の動作に一貫性がなく、障害のデバッグが困難であるため、問題となります。
document.write() の問題を解決するには、document.write() を使用しないことです。Chrome 53 以降では、document.write() の使用に問題がある場合、Chrome DevTools によってコンソールに警告が記録されます。
document.write() の使用にフラグが設定されます。このエラーが表示された場合は、サイトを確認してください。document.write()使用方法を探すHTTP ヘッダーブラウザに送信されました。
Lighthouse では、document.write() を使用しているサードパーティ スクリプトをハイライト表示することもできます。
document.write() を使用しているスクリプトを示す Lighthouse レポート。タグ マネージャーを使用する場合の注意点
タグは、デジタル マーケティング チームがデータを収集したり、Cookie を設定したり、ソーシャル メディア ウィジェットなどの第三者のコンテンツをサイトに統合したりできるようにするコード スニペットです。これらのタグは、ネットワーク リクエスト、JavaScript の依存関係、その他のリソースをページに追加します。これらはページのパフォーマンスに影響を与える可能性があり、タグが追加されるほど、ユーザーへの影響を最小限に抑えることが難しくなります。
ページの読み込みを高速に保つには、Google タグ マネージャー(GTM)などのタグ マネージャーを使用することをおすすめします。GTM を使用すると、タグを非同期でデプロイできるため、タグの読み込みが互いにブロックされることがなくなります。また、ブラウザがタグを実行するために必要なネットワーク呼び出しの数が減り、データレイヤ UI でタグデータが収集されます。
タグ マネージャーを使用するリスク
タグ マネージャーはページ読み込みを効率化するように設計されていますが、不注意に使用すると、次のような理由で読み込みが遅くなる可能性があります。
- タグ マネージャーに過剰な数のタグと自動イベント リスナーがあると、ブラウザは必要以上のネットワーク リクエストを行うことになり、コードがイベントに迅速に応答する能力が低下します。
- 認証情報とアクセス権を持つユーザーは、タグ マネージャーに JavaScript を追加できます。これにより、ページの読み込みに必要なコストの高いネットワーク リクエストの数が増えるだけでなく、不要なスクリプトによるセキュリティ リスクやその他のパフォーマンスの問題が発生する可能性もあります。これらのリスクを軽減するため、タグ マネージャーへのアクセスを制限することをおすすめします。
グローバル スコープを汚染するスクリプトを避ける
サードパーティ スクリプトは、さまざまな方法でページを予期せず破損させる可能性があります。
- JavaScript の依存関係を読み込むスクリプトは、コードと適切にやり取りしないコードでグローバル スコープを汚染する可能性があります。
- 予期しない更新により、互換性を破る変更が発生する可能性があります。
- サードパーティのコードは、転送中に変更され、ページのテスト時とデプロイ時で異なる動作をする可能性があります。
読み込むサードパーティ スクリプトを定期的に監査して、不正なアクターをチェックすることをおすすめします。また、自己テスト、サブリソースの完全性、サードパーティ コードの安全な送信を実装して、ページの安全性を維持することもできます。
緩和戦略
サードパーティ スクリプトがサイトのパフォーマンスとセキュリティに与える影響を最小限に抑えるための大規模な戦略をいくつかご紹介します。
HTTPS: HTTPS を使用するサイトは、HTTP を使用するサードパーティに依存してはなりません。詳しくは、混在コンテンツをご覧ください。
サンドボックス化:
sandbox属性を持つ iframe でサードパーティ スクリプトを実行して、スクリプトで使用できるアクションを制限することを検討してください。コンテンツ セキュリティ ポリシー(CSP): サーバーのレスポンスで HTTP ヘッダーを使用して、サイトの信頼できるスクリプトの動作を定義し、クロスサイト スクリプティング(XSS)などの攻撃の影響を検出して軽減できます。
次の例は、CSP の script-src ディレクティブを使用して、ページの許可された JavaScript ソースを指定する方法を示しています。
// Given this CSP header Content-Security-Policy: script-src
https://example.com/ // The following third-party script will not be loaded or
executed
<script src="https://not-example.com/js/library.js"></script>
関連情報
サードパーティの JavaScript の最適化について詳しくは、以下をご覧ください。
- パフォーマンスとレジリエンス: サードパーティのストレステスト
- JavaScript でインタラクティブな機能を追加する
- サードパーティ スクリプトの潜在的な危険性
- サードパーティ スクリプトをウェブ上でパフォーマンスの高い市民にする方法
- 高速化が重要な理由 - CSS Wizardry
- JavaScript サプライ チェーンのパラドックス: SRI、CSP、サードパーティ ライブラリの信頼性
- サードパーティの CSS は安全ではない
レビューにご協力いただいた Kenji Baheux、Jeremy Wagner、Pat Meenan、Philip Walton、Jeff Posnick、Cheney Tsai の各氏に感謝いたします。