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

読み込み時間とユーザー エクスペリエンスを改善するために、サードパーティのスクリプトを使用する際に陥りやすい落とし穴を避ける。

サードパーティのスクリプトによってページの読み込みが遅くなっている場合は、次の 2 つの方法でパフォーマンスを改善できます。

  • サイトに明確な価値を付加しない場合は削除してください。

  • 読み込みプロセスを最適化する。

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

  1. <script> タグで async 属性または defer 属性を使用する

  2. 必要な送信元への早期接続を確立

  3. 遅延読み込み

  4. 第三者スクリプトの提供方法の最適化

async または defer を使用します。

同期スクリプトは DOM の構築とレンダリングに遅延を発生させるため、ページをレンダリングする前にスクリプトを実行する必要がない限り、第三者のスクリプトを常に非同期で読み込む必要があります。

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

<script async src="script.js">

<script defer src="script.js">

asyncdefer の違いは、スクリプトの実行を開始するタイミングです。

async

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

async 属性を使用したパーサー ブロック スクリプトの図

defer

defer 属性が指定されたスクリプトは、HTML 解析が完全に終わった後、DOMContentLoaded イベントの前に実行されます。defer は、スクリプトが HTML に出現する順序で実行され、パーサーをブロックしないことを保証します。

defer 属性を含むスクリプトを使用したパーサーフローの図

  • 読み込みプロセスの早い段階でスクリプトを実行する必要がある場合は、async を使用します。

  • 重要性の低いリソースには defer を使用します。たとえば、スクロールしなければ見えない位置にある動画プレーヤー。

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

必要な送信元への早期接続を確立

重要なサードパーティの送信元への早期の接続を確立することで、100 ~ 500 ミリ秒を節約できます。

この場合、2 つの <link> タイプが役立ちます。

  • preconnect

  • dns-prefetch

preconnect

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

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

dns-prefetch

<link rel="dns-prefetch> は、<link rel="preconnect"> で処理される内容のごく一部を処理します。接続の確立には、DNS ルックアップと TCP handshake が必要です。安全なオリジンの場合は、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">

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

埋め込みのサードパーティ リソースは、構成が不十分な場合にページ速度低下の大きな原因となります。重要でない場合や、スクロールしなければ見えない範囲にある場合(つまり、ユーザーがスクロールしないと表示できない場合)、遅延読み込みはページ速度とペイント指標を改善するのに適した方法です。これにより、メインページのコンテンツが速く表示されるようになり、ユーザー エクスペリエンスが向上します。

モバイル デバイスに表示されたウェブページの図。画面外にスクロール可能なコンテンツが表示されている。スクロールしなければ見えない範囲のコンテンツは、まだ読み込まれていないため彩度が低くなります。

効果的な方法の 1 つは、メインページ コンテンツが読み込まれた後にサードパーティのコンテンツを遅延読み込みする方法です。このアプローチでは、広告が有力候補となります。

多くのサイトにとって広告は重要な収入源ですが、ユーザーはコンテンツを求めてやってきます。広告を遅延読み込みし、メイン コンテンツを迅速に配信することで、広告の全体的な視認性の割合を高めることができます。たとえば、MediaVine では広告の遅延読み込みに切り替えたことで、ページの読み込み速度が 200% 向上しました。DoubleClick の公式ドキュメントに、広告を遅延読み込みする方法が記載されています。

別の方法として、ユーザーがページの該当セクションまでスクロールしたときにのみ第三者のコンテンツを読み込むこともできます。

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

loading 属性を使用して画像や iframe を遅延読み込みする方法は、JavaScript の手法に代わる優れた手段であり、最近 Chrome 76 でご利用いただけるようになりました。

第三者スクリプトの配信方法を最適化する

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

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

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

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

自己ホストのサードパーティ スクリプト

自己ホスティングのサードパーティ スクリプトは、スクリプトの読み込みプロセスをより詳細に制御できるオプションです。セルフホスティングを使用すると、次のことが可能になります。

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

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

ただし、セルフホスティングには大きな欠点が 1 つあります。それは、API の変更やセキュリティ修正があっても、スクリプトが古くなり、自動更新を受け取れないということです。

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

セルフホスティングの代わりに、サードパーティの CDN のメリットを享受しながら、キャッシュをより詳細に制御する代わりに、Service Worker を使用してサードパーティ サーバーのスクリプトをキャッシュに保存するという方法もあります。これにより、ネットワークからスクリプトを再取得する頻度を制御し、ページが主要なユーザー操作に到達するまで、重要でないサードパーティ リソースのリクエストを抑制する読み込み戦略を作成できるようになります。この場合、preconnect を使用して早期接続を確立することも、ネットワーク コストをある程度削減できます。