サードパーティの JavaScript を効率的に読み込む

サードパーティ スクリプトがページの読み込みを遅らせている場合は、パフォーマンスを改善するために次の 2 つの方法があります。

  • サイトに明確な価値をもたらさない場合は削除します。
  • 読み込みプロセスを最適化する。

この記事では、次の手法を使用してサードパーティ スクリプトの読み込みプロセスを最適化する方法について説明します。

  • <script> タグの async 属性または defer 属性を使用する
  • 必要なオリジンへの早期接続の確立
  • 遅延読み込み
  • サードパーティ スクリプトの配信方法の最適化

同期スクリプトは DOM の構築とレンダリングを遅らせるため、ページをレンダリングする前にスクリプトを実行する必要がある場合を除き、サードパーティ スクリプトは常に非同期で読み込む必要があります。

async 属性と defer 属性は、バックグラウンドでスクリプトを読み込みながら HTML の解析を続行し、読み込み後にスクリプトを実行できることをブラウザに伝えます。これにより、スクリプトのダウンロードが DOM の構築やページのレンダリングをブロックしなくなり、すべてのスクリプトの読み込みが完了する前にユーザーにページを表示できるようになります。

<script async src="script.js">

<script defer src="script.js">

async 属性と defer 属性の違いは、ブラウザがスクリプトを実行するタイミングです。

async

async 属性を持つスクリプトは、ダウンロードが完了した後、ウィンドウの load イベントの前に、最初の機会で実行されます。つまり、async スクリプトが HTML に表示される順序で実行されない可能性があります(そして、その可能性は高いです)。また、パーサーがまだ動作している間にダウンロードが完了すると、DOM の構築が中断される可能性があります。

async 属性を持つスクリプトをブロックするパーサーの図
async を含むスクリプトは、引き続き HTML 解析をブロックできます。

defer

defer 属性を持つスクリプトは、HTML 解析が完全に完了した後、DOMContentLoaded イベントの前に実行されます。defer を使用すると、スクリプトが HTML に表示される順序で実行され、パーサーがブロックされなくなります。

defer 属性を含むスクリプトを使用したパーサーフロー図
defer を含むスクリプトは、ブラウザが HTML の解析を完了するまで実行を待機します。
  • 読み込みプロセスの早い段階でスクリプトを実行することが重要な場合は、async を使用します。
  • defer は、折りたたみ式の動画プレーヤーなど、重要度の低いリソースに使用します。

これらの属性を使用すると、ページの読み込み時間を大幅に短縮できます。たとえば、Telegraph は広告やアナリティクスを含むすべてのスクリプトを遅延し、広告の読み込み時間を平均 4 秒短縮しました。

必要なオリジンへの早期接続を確立する

重要なサードパーティ オリジンへの早期接続を確立することで、100 ~ 500 ms を節約できます。

ここでは、preconnectdns-prefetch の 2 つの <link> タイプが役立ちます。

preconnect

<link rel="preconnect"> は、ページが他のオリジンへの接続を確立しようとしていることと、プロセスをできるだけ早く開始する必要があることをブラウザに通知します。ブラウザが事前に接続されたオリジンからリソースをリクエストすると、ダウンロードがすぐに開始されます。

<link rel="preconnect" href="https://cdn.example.com">

dns-prefetch

<link rel="dns-prefetch> は、<link rel="preconnect"> が処理するもののサブセットを処理します。接続の確立には、DNS ルックアップと TCP ハンドシェイクが含まれます。安全なオリジンの場合は、TLS ネゴシエーションも含まれます。dns-prefetch は、明示的に呼び出される前に特定のドメインの DNS のみを解決するようにブラウザに指示します。

preconnect ヒントは、最も重要な接続にのみ使用することをおすすめします。重要度の低いサードパーティのドメインには <link rel=dns-prefetch> を使用します。

<link rel="dns-prefetch" href="http://example.com">

dns-prefetch のブラウザ サポートpreconnect のサポートとは若干異なるため、dns-prefetchpreconnect をサポートしていないブラウザの代替として使用できます。安全に実装するには、個別のリンクタグを使用します。

<link rel="preconnect" href="http://example.com">
<link rel="dns-prefetch" href="http://example.com">

サードパーティ リソースを遅延読み込みする

埋め込みサードパーティ リソースが適切に構築されていないと、ページの読み込みが大幅に遅くなる可能性があります。重要な要素ではなく、折り返しの下にある要素(つまり、ユーザーがスクロールして表示する必要がある要素)の場合は、遅延読み込みがページの速度とペイント指標を改善する効果的な方法です。これにより、ユーザーはメインページのコンテンツをより速く取得し、優れたエクスペリエンスを得ることができます。

モバイル デバイスに表示されたウェブページの図。画面外にスクロール可能なコンテンツが広がっています。折り返しの下にあるコンテンツは、まだ読み込まれていないため、色が薄くなっています。
スクロールしなければ見えない範囲のコンテンツを遅延読み込みで表示する。

効果的なアプローチの一つは、メインページのコンテンツの読み込み後にサードパーティ コンテンツを遅延読み込みすることです。広告は、このアプローチに適しています。

広告は多くのサイトにとって重要な収益源ですが、ユーザーはコンテンツを求めてサイトにアクセスします。広告を遅延読み込みし、メイン コンテンツをより速く配信することで、広告の全体的な視認可能率を高めることができます。たとえば、MediaVine は遅延読み込み広告に切り替えた結果、ページの読み込み速度が 200% 向上しました。Google アド マネージャーには、広告を遅延読み込みする方法に関するドキュメントがあります。

ユーザーがページのそのセクションに初めてスクロールしたときにのみサードパーティ コンテンツを読み込むように設定することもできます。

Intersection Observer は、要素がブラウザのビューポートに移動したタイミングを効率的に検出するブラウザ API です。この API を使用して、この手法を実装できます。lazysizes は、画像と iframes の遅延読み込みに使用される一般的な JavaScript ライブラリです。YouTube の埋め込みとウィジェットをサポートしています。また、Intersection Observer のオプションのサポートも用意されています。

画像と iframe の遅延読み込みに loading 属性を使用することは、JavaScript 手法の優れた代替手段です。この方法は最近、Chrome 76 で利用可能になりました。

サードパーティ スクリプトの配信方法を最適化する

サードパーティ スクリプトの使用を最適化するための推奨戦略をいくつかご紹介します。

サードパーティの CDN ホスティング

サードパーティ ベンダーは、通常はコンテンツ配信ネットワーク(CDN)でホストしている JavaScript ファイルの URL を提供するのが一般的です。このアプローチのメリットは、URL をコピーして貼り付けるだけですぐに使用を開始できることと、メンテナンス オーバーヘッドがないことです。サードパーティ ベンダーがサーバー構成とスクリプトの更新を処理します。

ただし、他のリソースと同じオリジンにないため、パブリック CDN からファイルを読み込むとネットワーク費用が発生します。ブラウザは DNS ルックアップを実行し、新しい HTTP 接続を確立し、安全なオリジンでベンダーのサーバーとの SSL ハンドシェイクを実行する必要があります。

サードパーティ サーバーからファイルを使用する場合、キャッシュを制御することはほとんどありません。他者のキャッシュ戦略に依存すると、スクリプトがネットワークから不必要に頻繁に再取得される可能性があります。

サードパーティ スクリプトをセルフホストする

サードパーティ スクリプトをセルフホストすると、スクリプトの読み込みプロセスをより細かく管理できます。セルフホストすると、次のことができます。

  • DNS ルックアップとラウンドトリップの時間を短縮します。
  • HTTP キャッシュ ヘッダーを改善。
  • HTTP/2 または新しい HTTP/3 を利用します。

たとえば、Casper は A/B テスト スクリプトをセルフホストすることで、読み込み時間を 1.7 秒短縮しました。

ただし、セルフホスティングには大きな欠点があります。スクリプトが古くなる可能性があり、API の変更やセキュリティ修正が行われても自動更新されません。

Service Worker を使用してサードパーティ サーバーからのスクリプトをキャッシュする

セルフホストの代わりに、サービス ワーカーを使用してサードパーティ サーバーからスクリプトをキャッシュに保存することもできます。これにより、サードパーティ CDN のメリットを維持しながら、キャッシュをより細かく制御できます。

ネットワークからスクリプトを再取得する頻度を制御し、ユーザーがページ上の重要な操作を行うまで、必須ではないサードパーティ リソースのリクエストをスロットリングする読み込み戦略を作成できます。preconnect を使用すると、早期に接続を確立し、ネットワーク費用を軽減できます。