mcpField
T
third-party

third-party

github.com/patternsdev開発2571.5k 回インストール28 週間前に更新
リポジトリ

third-party について

third-party は、外部スクリプトや埋め込みコンテンツを扱う Web 開発者向けのパフォーマンスガイドです。遅延実行、接続の事前確立、遅延読み込みに加え、セルフホストやキャッシュも説明します。

主な機能

  1. 01async または defer によるスクリプト遅延
  2. 02preconnect と dns-prefetch の利用
  3. 03画面下部の埋め込みの遅延読み込み
  4. 04サードパーティの性能影響の評価
  5. 05セルフホストとキャッシュの検討

活用シーン

  1. 01分析スクリプトによる描画ブロックの軽減
  2. 02動画や地図の埋め込み読み込みの遅延
  3. 03外部コードによるページ性能への影響評価

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/patternsdev/skills --skill third-party

インストール後、Claude Code で/third-partyを入力して読み込まれたか確認します。

詳細

サードパーティの読み込みを最適化する

目次

使用する場面

  • アナリティクス、広告、チャットウィジェット、ソーシャルメディアの埋め込みなどのサードパーティスクリプトがサイトの速度を低下させている場合に使用します。
  • 重要なサードパーティ機能を維持しながら、Core Web Vitals を最適化するのに役立ちます。

手順

  • 重要度の低いサードパーティスクリプトには、async または defer 属性を使用します。
  • preconnect と dns-prefetch のリソースヒントを使って、早期に接続を確立します。
  • スクロールしないと表示されない埋め込みコンテンツ(YouTube、地図、ソーシャルメディア)は、IntersectionObserver またはファサードを使って遅延読み込みします。
  • キャッシュをより適切に制御するため、重要なサードパーティスクリプトのセルフホストを検討します。
  • フレームワークレベルで最適化するには、適切な strategy 値を指定して Next.js Script コンポーネントを使用します。

詳細

他のサイトと切り離されて運営されている現代的なサイトを見つけるのは困難です。ほとんどのサイトは、データ、機能、コンテンツなどを得るために、ウェブ上の複数の情報源と共存し、それらに依存しています。別のドメインにあるリソースをサイトで利用する場合、そのサイトにとってそれはサードパーティ(3P)リソースです。サイトに含まれるサードパーティリソースの一般的な例は次のとおりです。

  • 地図、動画、ソーシャルメディア、チャットサービスの埋め込み
  • 広告
  • アナリティクスコンポーネントとタグマネージャー
  • A/B テストおよびパーソナライズ用スクリプト
  • データの可視化やアニメーションなどに使う、すぐに利用できるヘルパー関数を提供するユーティリティライブラリ
  • ボット検出用の reCAPTCHA または CAPTCHA

サードパーティを利用すると、コンテンツに価値を加える機能を統合したり、サイトをゼロから構築する手間を減らしたりできます。2021 年の Web Almanac レポートによると、ウェブ上のページの 94% 以上がサードパーティを利用しており、画像と JavaScriptがサードパーティコンテンツの大部分を占めています。

サードパーティリソースは便利な機能でサイトを充実させる一方、次の場合にはサイトの速度を低下させることがあります。

  • 必要なリソースごとに、サードパーティのドメインへの追加の往復通信が発生する。
  • JavaScript を多用している(ダウンロード時間や実行時間に影響する)、または画像や動画が最適化されておらず、サイズが大きい。
  • 個々のサイト所有者が実装に影響を与えられず、挙動が予測できないことがある。
  • ページ上の他の重要なリソースのレンダリングを妨げ、Core Web Vitals(CWV)に影響することがある。

こうした問題がある一方で、サードパーティはビジネスに不可欠な場合があります。3P をなくせない場合、次善の策は、パフォーマンスへの影響を抑えるために最適化することです。

3P リソースによるパフォーマンスへの影響を評価する

サードパーティコードがサイトに与える影響を調べるには、複数の手法を組み合わせて使用できます。

最適化戦略

サードパーティのコードは管理できないため、ライブラリを直接最適化することはできません。そのため、選択肢は2つあります。

  1. 置き換える、または削除する:サードパーティのスクリプトによる価値が、パフォーマンスへの負荷に見合わない場合は、削除を検討してください。同様の機能を提供する軽量な代替手段を評価することもできます。

  2. 読み込み順序を最適化する:読み込み処理では、ブラウザーで複数のファーストパーティおよびサードパーティのリソースを読み込みます。最適な読み込み戦略を設計するには、ブラウザーが各リソースに割り当てる優先度、ページ上の位置、ウェブページにとっての各リソースの価値を考慮する必要があります。

3P スクリプトを効率よく読み込む

以下は、適切に利用することでサードパーティリソースによるパフォーマンスへの影響を軽減できる、実績のあるベストプラクティスです。

async または defer を使用して、スクリプトがほかのコンテンツをブロックしないようにします。

対象: 重要ではないスクリプト(タグマネージャー、分析ツール)

JavaScript のダウンロードと実行はデフォルトで同期的に行われるため、メインスレッド上で HTML パーサーと DOM の構築をブロックすることがあります。<script> 要素で async または defer 属性を使用すると、ブラウザーにスクリプトを非同期でダウンロードするよう指示できます。これらは、クリティカルレンダリングパスに必要ないスクリプト(メイン UI コンポーネントなど)のダウンロードに使用できます。

  • defer:パーサーの実行と並行してスクリプトを取得し、解析が完了するまでスクリプトの実行を遅らせます。DOM の構築後まで実行を遅らせる場合は、defer をデフォルトの選択肢にしてください。
  • async:解析中にスクリプトを並行して取得し、利用可能になり次第、パーサーをブロックして実行します。依存関係のあるモジュールスクリプトの場合、スクリプトとそのすべての依存関係は defer キューで実行されます。読み込み処理の早い段階で実行する必要があるスクリプトには async を使用してください。たとえば、ページ読み込み直後のデータを取りこぼさずに、特定の分析スクリプトを早期に実行したい場合などです。
<script src="https://example.com/deferthis.js" defer></script>
<script src="https://example.com/asyncthis.js" async></script>

ここで触れておきたい注意点として、async と defer はブラウザーがリソースに割り当てる優先度を下げるため、読み込みが大幅に遅くなることがあります。優先度ヒントの新機能を使うと、この問題を回避できます。

リソースヒントを使用して、必要なオリジンへの接続を早期に確立する

対象: サードパーティ CDN から読み込むクリティカルなスクリプト、フォント、CSS、画像

サードパーティのオリジンへの接続には、DNS ルックアップ、リダイレクト、各サードパーティサーバーに必要な複数回の往復通信が伴うため、時間がかかることがあります。リソースヒントの dns-prefetch と preconnect を使うと、ライフサイクルの早い段階で接続を開始し、準備にかかる時間を短縮できます。

ドメインに対応する dns-prefetch リソースヒントを指定すると、DNS ルックアップが早期に実行され、DNS ルックアップに伴う遅延が軽減されます。最もクリティカルなリソースには、これと preconnect を組み合わせることができます。preconnect は DNS ルックアップに加えて、TCP の往復通信と TLS ネゴシエーションを行い、サードパーティのドメインへの接続を開始します。

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

リソースヒントを使用するメリットは、この事例で明らかです。Andy Davies は、サードパーティの画像 CDN への接続を早期に開始することで、メインの商品画像の読み込み時間をpreconnect によって短縮した方法を解説しています。

同様に、ボット検出(reCaptcha)や同意管理など、クリティカルなサードパーティの読み込み時間を最適化するために、リソースヒントを使用できます。

ページ下部にあるサードパーティーリソースを遅延読み込みする

対象: YouTube、Maps、広告、ソーシャルメディアなどの埋め込み

ソーシャルメディアのフィード、広告、YouTube 動画、マップなどに使われるサードパーティーの埋め込みは、ウェブページの表示を遅くすることがあります。ただし、ページの読み込み時にユーザーに表示されるとは限らないため、ユーザーがスクロールして表示位置に近づいたときに遅延読み込みできます。必要なブラウザーサポートに応じて、さまざまな遅延読み込みの方法を利用できます。

  1. YouTube や Google Maps などの埋め込みを読み込む際によく使われる画像や iframe には、loading 属性を使用できます。
  2. IntersectionObserver API を使ったカスタム実装では、監視対象の要素がブラウザーのビューポートに入ったとき、またはビューポートから出たときを検出できます。
  3. Lazy-sizes — 遅延読み込みを実装する、人気の JavaScript ライブラリです。

埋め込みの遅延読み込みを応用した方法として、ページの読み込み時にユーザーに表示する静的または動的なファサードを使う方法があります。マップの埋め込みの代わりに、実際の埋め込みの静止画像を使用できます。マップには Map Static API、Twitter の埋め込みには Tweetpik、YouTube には lite-youtube-embed、チャットウィジェットには React-live-chat-loader などのソリューションがあります。これらの手法についての詳しい説明はこちらをご覧ください。

遅延読み込みとファサードに関する注意点は次のとおりです。

  • YouTube ファサードの動作は、iOS と macOS 11 以降の Safari では少し異なります。最初にタップまたはクリックすると、実際の動画埋め込みが読み込まれます。動画を再生するには、もう一度タップする必要があります。
  • 埋め込みのサイズが指定されていないと、遅延読み込みによってレイアウトシフトが発生し、ユーザー体験に影響することがあります。レイアウトシフトを防ぐには、遅延読み込みするすべての埋め込み、またはそのコンテナー要素のサイズを指定してください。
往復通信を防ぐためにサードパーティーのスクリプトをセルフホストする

対象: JavaScript ファイル、フォント

preconnect または dns-prefetch を使うと、サードパーティーのオリジンへの接続を早期に開始できますが、接続自体は依然として必要です。また、サードパーティーのオリジンを使う場合、そのキャッシュ戦略に依存する必要があり、最適とは限りません。

スクリプトのコピーを同じオリジンでセルフホストすると、スクリプトの読み込みやキャッシュのプロセスをより細かく制御できます。セルフホストによって DNS ルックアップにかかる時間を短縮でき、HTTP キャッシュを使ってスクリプトのキャッシュ戦略を改善できます。また、ユーザーが必要とすることがわかっているスクリプトをプッシュするために、HTTP/2 サーバープッシュも利用できます。サードパーティーのスクリプトをセルフホストする好例として、Optimizely が提供するサードパーティーのスクリプトをセルフホストし、ホームページのレンダリング開始時間を 1.7 秒短縮した Casper.com があります。

サードパーティーのスクリプトのコピーをセルフホストする場合は、元のスクリプトの変更に応じて、コピーを定期的に更新する必要があります。更新しないと、スクリプトが古くなり、依存関係に関する重要な修正や変更が反映されない可能性があります。また、CDN ではなくサーバーでセルフホストすると、CDN が採用しているエッジキャッシュの仕組みを活用できなくなります。

可能な場合は、サービスワーカーを使ってスクリプトをキャッシュする

対象: JavaScript ファイル、フォント

頻繁に変更されるスクリプトは、セルフホストできない場合があります。サービスワーカーを使えば、CDN エッジキャッシュも活用しながら、このようなサードパーティ製スクリプトのキャッシュを改善できます。この手法により、ネットワーク経由で再取得する頻度をより細かく制御できます。また、プリコネクトと組み合わせることで、フェッチ処理のネットワークコストをさらに削減できます。ページが重要なユーザーアクションのタイミングに達するまで、必須ではないサードパーティ製スクリプトのリクエストを遅らせるようにリソースを読み込むこともできます。

理想的な読み込み順序に従う

サードパーティの種類や、ページにとっての価値については、上記のガイダンスを参考にしてください。各リソースの用途に応じて、ファーストパーティとサードパーティのリソースを最適な順序で組み合わせることで、ページの読み込みを高速化できます。

スクリプトの種類別のベストプラクティス

スクリプトによっては、他のものより最適化しやすいものがあります。一般的には、ユーザーは一定量のコンテンツが表示されるまでは、サイトを操作しないと考えられています。

重要でない JavaScript

チャットウィジェットや分析スクリプトなど、大半のサードパーティ製スクリプトはユーザー体験に不可欠ではないため、読み込みを遅らせることができます。これらのスクリプトの読み込みと実行を遅らせる最も一般的な方法は、defer スクリプト属性を使用することです。

広告や分析のチームは、スクリプトの遅延によるアプリの可視性や広告収益への影響を懸念するかもしれません。この文脈では、Telegraph の事例研究がよく引用されます。この事例では、すべてのスクリプトを遅延させても、分析や広告の指標に偏りは生じませんでした。それどころか、First Ad Loaded 指標は平均 4 秒改善しました。

ボット検出/ReCaptcha

ボットによるウェブフォームへのアクセスを防ぐ必要があるため、開発者は通常、これらのスクリプトをできるだけ早く読み込みます。ただし、ReCaptcha は JS ペイロードが大きく、メインスレッドへの負荷も大きいため、必要になるまで読み込みを遅らせるメリットがあります。このスクリプトを最適化する方法をいくつか紹介します。

  1. ボットにスパムされる可能性のあるユーザー入力フォームがある、限られたページでのみ読み込みます。
  2. フォームへのフォーカス時など、ユーザーがフォーム要素を操作したタイミングでスクリプトを遅延読み込みします。
  3. ページの読み込み時にスクリプトを実行する必要がある場合は、リソースヒントを使って接続を早期に確立します。
Google Tag Manager (GTM)

大規模なサイトでは、マーケティングチームや代理店にGoogle Tag Managerへのアクセス権を付与することがよくあります。これにより、サイト内のすべてのページに新しいマーケティングタグを追加して、トラッキングを改善できます。マーケティングチームにとってパフォーマンスは最優先事項ではなく、配慮なくタグを追加するとサイトが遅くなることを知らないメンバーもいるでしょう。GTM スクリプトの最適化では、GTM にアクセスできるユーザーを管理することと、ユーザーによる変更を監視することが重要です。

まず、アカウントを外部代理店ではなく、サイトの所有者が所有していることを確認します。これにより、タグの追加、編集、公開を行えるユーザーに対して、詳細なアクセス権限を設定できます。また、開発部門とマーケティング部門の連携を強化し、新しいタグを監査したり、使用されていないタグを削除したりできます。

サイトのすべてのページで GTM が必要とは限りません。ページごとに監査を行い、不要な GTM の読み込みを削除してください。クッキーバナーを使用しているサイトでは、ユーザーがクッキーを拒否した場合に GTM を読み込まない選択もできます。最後に、ページで GTM を読み込む必要がある場合は、メインコンテンツの読み込み後にスクリプトを実行するよう遅らせることができます。

A/B テストとパーソナライゼーション

サイトでは、どちらのバージョンのウェブページのパフォーマンスが優れているかを確認するために、A/B テストを実施します。A/B テストは、実施するページのパフォーマンスに大きな影響を与えることがあり、テストごとに読み込み時間が最大 1 秒増加します。現在、多くの A/B テストは外部のサードパーティを通じて提供されており、開発者はテスト用に UI を変更する JavaScript コードの実行をほとんど制御できません。

サイトのパーソナライゼーションは関連する概念で、既知のデータに基づいて異なるユーザーに合わせたエクスペリエンスを提供するスクリプトを実行します。こうしたスクリプトも負荷が高く、最適化が困難です。A/B テストのスクリプトと同様に、パーソナライゼーションのスクリプトも、レンダリングされる UI がスクリプトの出力に依存するため、早い段階で実行する必要があります。A/B テストとパーソナライゼーション向けのカスタムサーバーベースのソリューションを開発するのが、A/B テストを最適化する理想的な方法です。ただし、常に実現可能とは限りません。

サードパーティの A/B テストスクリプトを最適化するには、スクリプトを受け取るユーザー数を制限できます。Google Optimize では、ユーザーをターゲットにするルールを設定できます。

YouTube とマップの埋め込み

これらの埋め込みは負荷が高いため、最適化するには遅延読み込みやクリックして読み込むパターンを検討する必要があります。lite-youtube-embedのようなソリューションの利用が推奨されます。ただし、このファサードを使って動画を再生するには、iOS/macOS-Safari ではダブルタップ/クリックが必要です。

ソーシャルメディアの埋め込み

ソーシャルメディアの埋め込みには、スクリプトを遅延読み込みするオプションが用意されているものがあります(例:Facebookの埋め込みにおけるdata-lazy)。パフォーマンス向上のため、これを検討できます。別の方法として、手動で作成した画像ファサードや、tweetpikのようなツールを使って作成した画像ファサードを利用できます。

すぐに使える最適化

サードパーティを最適化するには、開発チームがリソースヒント、遅延読み込み、HTTP キャッシュ、サービスワーカーの詳細を理解し、それらをソリューションに実装する必要があります。一部のフレームワークやライブラリでは、こうしたベストプラクティスが開発者にとって使いやすい形でまとめられています。

Builder.io が作成した Partytownは、リソースを大量に消費するスクリプトをメインスレッドではなくウェブワーカーで実行できるようにする実験的なライブラリです。その理念は、メインスレッドを自分のコード専用にし、クリティカルパスで必要とされないスクリプトはウェブワーカー内でサンドボックス化して分離することです。Partytown では、Cookie、localStorage、userAgent などのメインスレッド API へのアクセスを設定できます。API 呼び出しを引数とともに記録することで、スクリプトの動作をより詳しく把握することもできます。

JavaScript プロキシとサービスワーカーが、ウェブワーカーとメインスレッド間の通信を処理します。Partytown のスクリプトは、HTML ドキュメントと同じサーバーでセルフホストする必要があります。React や Next.js のアプリで、またはフレームワークを使わずに利用できます。ウェブワーカーで実行できる各サードパーティスクリプトは、次のように開始タグの type 属性を text/partytown に設定する必要があります。

<script type="text/partytown">// Third-party analytics scripts</script>

このライブラリには、React または Next.js のプロジェクトに直接含められる React Partytown コンポーネントも用意されています。

import { Partytown } from '@builder.io/partytown/react';
import Document, { Html, Head, Main, NextScript } from 'next/document';

export default class MyDocument extends Document {
 render() {
   return (
     <Html>
       <Head>
         <Partytown />
       </Head>
       <body>
         <Main />
         <NextScript />
       </body>
     </Html>
   );
 }

Partytown には、Google Tag Manager など、一般的な分析ライブラリ向けの React コンポーネントも含まれています。

import { Partytown, GoogleTagManager, GoogleTagManagerNoScript } from '@builder.io/partytown/react';
import Document, { Html, Head, Main, NextScript } from 'next/document';

export default class MyDocument extends Document {
 render() {
   return (
     <Html>
       <Head>
         <GoogleTagManager containerId={'GTM-XXXXX'} />
         <Partytown />
       </Head>
       <body>
         <GoogleTagManagerNoScript containerId={'GTM-XXXXX'} />
         <Main />
         <NextScript />
       </body>
     </Html>
   );
 }
Next.js Script コンポーネント

Next.js 11 は、Google の Aurora チームが導入した Conformance 手法に基づくコンポーネントとともに、2021 年半ばにリリースされました。Next.js Script コンポーネント は、読み込みパフォーマンスを改善するカスタマイズ可能なテンプレートを提供することで、Conformance を活用しています。Script コンポーネントは <script> タグをカプセル化し、strategy 属性を使ってサードパーティスクリプトの読み込み優先度を設定できます。strategy 属性には、次の 3 つの値を指定できます。

  1. beforeInteractive:ブラウザーがページをインタラクティブにする前に実行する必要がある、重要なスクリプトに使用します。(例:ボット検出)
  2. afterInteractive:ページがインタラクティブになった後にブラウザーが実行できるスクリプトに使用します。(例:タグマネージャー)これはデフォルトで適用される戦略であり、スクリプトを defer 付きで読み込むのと同等です。
  3. lazyOnload:ブラウザーがアイドル状態のときに遅延読み込みできるスクリプトに使用します。

strategy を設定すると、読み込み順序を最適化しながら、Next.js がスクリプト読み込み時の最適化とベストプラクティスを自動的に適用できます。

変更前:

import Head from "next/head";

export default function Home() {
  return (
    <>
      <Head>
        <script async src="https://example.com/samplescript.js" />
      </Head>
    </>
  );
}

変更後:

import Script from 'next/script'

export default function Home() {
 return (
   <>
     <Script src="https://example.com/samplescript.js" />
   </>
 )
}
ポリフィルを早期に読み込む

コアコンテンツに適用する特定のポリフィルを早期に読み込む場合は、beforeInteractive 戦略を使用できます。

import Script from "next/script";

export default function Home() {
  return (
    <>
      <Script
        src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver"
        strategy="beforeInteractive"
      />
    </>
  );
}
ソーシャルメディアの埋め込みコンテンツを遅延読み込みする

ソーシャルメディアの埋め込みコンテンツは、特にページ読み込み時に表示されないものについては、読み込みを遅らせたり、遅延読み込みしたりできます。lazyOnload 戦略を使用できます。

import Script from "next/script";

export default function Home() {
  return (
    <>
      <Script
        src="https://connect.facebook.net/en_US/sdk.js"
        strategy="lazyOnload"
      />
    </>
  );
}
読み込み時に条件付きでコードを実行する

特定のサードパーティが読み込まれた後に実行する必要があるコードもあります。Script コンポーネントの onLoad 属性で指定できます。

<Script
  src={url} // consent management
  strategy="beforeInteractive"
  onLoad={() => {
    // If loaded successfully, then you can load other scripts in sequence
  }}
/>
script タグ内でインラインスクリプトを使用する

サードパーティコンポーネントの読み込み後に実行する必要があるインラインスクリプトも、Script コンポーネントに含めることができます。

import Script from 'next/script'

<Script id="show-banner" strategy="lazyOnload">
 {`document.getElementById('banner').removeClass('hidden')`}
</Script>

// or

<Script
 id="show-banner"
 dangerouslySetInnerHTML={{
   __html: `document.getElementById('banner').removeClass('hidden')`
 }}
/>

ここでは、インラインスクリプトを使って、サードパーティのバナー広告が遅延読み込みされた後にその表示状態を変更しています。インラインスクリプトは dangerouslySetInnerHTML 属性を使って含めることもできます。

属性をサードパーティスクリプトに渡す

Script コンポーネントで、サードパーティスクリプトが使用できる特定の属性値を設定できます。

import Script from "next/script";

export default function Home() {
  return (
    <>
      <Script
        src="https://www.google-analytics.com/analytics.js"
        id="analytics"
        nonce="XUENAJFW"
        data-test="analytics"
      />
    </>
  );
}
アナリティクススクリプトを読み込む

Google Analytics(GA)や Google Tag Manager(GTM)を使って、サイトにアナリティクスを導入する方法はいくつかあります。Script コンポーネントを使うと、Next.js サイトで gtag.js または analytics.js スクリプトを最適に読み込めます。

_app.js 内に Script コンポーネントを含めることで、サイト内のすべてのページで GTM を有効にできます。

import Script from "next/script";

function MyApp({ Component, pageProps }) {
  return (
    <>
      {/* Google Tag Manager - Global base code */}
      <Script
        strategy="afterInteractive"
        dangerouslySetInnerHTML={{
          __html: `
           (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
           new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
           j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
           'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
           })(window,document,'script','dataLayer', '${GTM_ID}');
         `,
        }}
      />
      <Component {...pageProps} />
    </>
  );
}
export default MyApp;

上記のどちらの例でも、アナリティクススクリプトは strategy = afterInteractive で読み込まれる点に注意してください。

まとめ

自分のサーバー上のリソースとウェブ上のほかの場所にあるリソースを組み合わせてウェブページを作成する場合、これらのリソースが相互に及ぼす影響を定期的に監視する必要があります。まず、リソースを適切な順序で読み込み、ベストプラクティスに従うことから始められます。また、ベストプラクティスを設計に組み込んだフレームワークやソリューションを利用することもできます。

サイトの成長に伴い、パフォーマンスの報告と定期的な監査によって、重複を排除し、パフォーマンスに影響するスクリプトを最適化できます。最後に、パフォーマンス上の問題が広く知られているサードパーティが自らコードを最適化するか、こうした問題への回避策を可能にする API を公開してくれることを期待できます。

出典

コメント