サードパーティの埋め込みを使用する際のベスト プラクティス

一般的なサードパーティの埋め込みを効率的に読み込むための手法の概要。

Addy Osmani
Addy Osmani
Katie Hempenius
Katie Hempenius
Leena Sohoni
Leena Sohoni

多くのサイトでは、サードパーティの埋め込みを使用して、ウェブページの一部のセクションを別のコンテンツ プロバイダに委任することで、魅力的なユーザー エクスペリエンスを実現しています。サードパーティ コンテンツの埋め込みの最も一般的な例としては、動画プレーヤー、ソーシャル メディア フィード、地図、広告などがあります。

第三者のコンテンツは、ページのパフォーマンスにさまざまな形で影響を与える可能性があります。レンダリングを妨げたり、ネットワークや帯域幅の他の重要なリソースと競合したり、Core Web Vitals の指標に影響を及ぼしたりする可能性があります。サードパーティの埋め込みも、読み込み時にレイアウト シフトを引き起こす可能性があります。この記事では、サードパーティの埋め込みを読み込む際に使用できるパフォーマンスのベスト プラクティス、効率的な読み込み手法、一般的な埋め込みでレイアウト シフトを減らすのに役立つ Layout Shift Terminator ツールについて説明します。

埋め込みとは

サードパーティ埋め込みとは、サイトに表示される次のようなコンテンツを指します。 * 作成者以外 * サードパーティのサーバーから配信される

オフスクリーン埋め込みが複数表示されるため、遅延読み込みされる可能性がある

埋め込みは次の場所でよく使用されます。 * スポーツ、ニュース、エンターテイメント、ファッションに関連するウェブサイトでは、動画を使用してテキスト コンテンツを補強します。 * 有効な Twitter アカウントやソーシャル メディア アカウントを持つ組織は、これらのアカウントのフィードをウェブページに埋め込んで、より多くのユーザーに働きかけることができます。 * レストラン、公園、イベント会場のページには多くの場合、地図が埋め込まれています。

サードパーティの埋め込みは通常、ページの <iframe> 要素に読み込まれます。サードパーティ プロバイダが提供する HTML スニペットのほとんどは、マークアップ、スクリプト、スタイルシートで構成されるページを読み込む <iframe> で構成されています。一部のプロバイダでは、<iframe> を動的に挿入して他のコンテンツを取り込むスクリプト スニペットを使用しています。これにより、サードパーティの埋め込みが重くなり、ファーストパーティ コンテンツの表示が遅れ、ページのパフォーマンスが低下する可能性があります。

サードパーティ埋め込みがパフォーマンスに及ぼす影響

一般的な埋め込みの多くには 100 KB を超える JavaScript が含まれており、場合によっては 2 MB に達することもあります。読み込みに時間がかかり、実行時にメインスレッドをビジー状態に維持します。LighthouseChrome DevTools などのパフォーマンス モニタリング ツールを使用すると、サードパーティ埋め込みがパフォーマンスに及ぼす影響を測定できます。

サードパーティのコードの影響を軽減する Lighthouse の監査では、ページで使用されているサードパーティ プロバイダのリストが、サイズとメインスレッドのブロック時間とともに表示されます。監査は、Chrome DevTools の [Lighthouse] タブで確認できます。

埋め込みソースコードは変更される可能性があるため、埋め込みとサードパーティ コードのパフォーマンスへの影響を定期的に監査することをおすすめします。この機会に冗長なコードを削除できます。

サードパーティ コードの影響を軽減する

読み込みのベスト プラクティス

サードパーティの埋め込みは、パフォーマンスに悪影響を与える可能性がありますが、重要な機能も提供します。サードパーティの埋め込みを効率的に使用し、パフォーマンスへの影響を軽減するには、以下のガイドラインに従ってください。

スクリプトの順序

適切に設計されたページでは、主要なファーストパーティ コンテンツがページのフォーカスとなり、サードパーティの埋め込みはサイドバーに重なるか、ファースト パーティ コンテンツの後に表示されます。

優れたユーザー エクスペリエンスを実現するには、メイン コンテンツを他のサポート コンテンツよりも早く読み込めるようにする必要があります。たとえば、ニュースページのニュース テキストは、Twitter フィードや広告を埋め込む前に読み込む必要があります。

サードパーティの埋め込みをリクエストすると、ファースト パーティ コンテンツの読み込みが妨げられる可能性があるため、サードパーティのスクリプトタグの位置は重要です。スクリプトの実行中に DOM 構築が一時停止するため、スクリプトが読み込みシーケンスに影響を与える可能性があります。主な自社タグの後に第三者スクリプトタグを配置し、async 属性または defer 属性を使用して非同期で読み込みます。

<head>
   <title>Order of Things</title>
   <link rel="stylesheet" media="screen" href="/assets/application.css">
   <script src="index.js"></script>
   <script src="https://example.com/3p-library.js" async></script>
</head>

遅延読み込み

通常、第三者のコンテンツはプライマリ コンテンツの後に配置されるため、ページの読み込み時にビューポートに表示されない場合があります。この場合、ユーザーがページのその部分までスクロールするまで、サードパーティのリソースのダウンロードを遅らせることができます。これにより、最初のページの読み込みが最適化されるだけでなく、固定データプランのユーザーや低速のネットワーク接続を使用するユーザーのダウンロード コストも削減できます。

実際に必要になるまでコンテンツのダウンロードを遅らせることを遅延読み込みと呼びます。要件と埋め込みの種類に応じて、以下で説明するさまざまな遅延読み込み手法を使用できます。

<iframe> のネイティブ遅延読み込み

<iframe> 要素を通じて読み込まれるサードパーティの埋め込みについては、ブラウザレベルの遅延読み込みを使用して、ユーザーがその近くをスクロールするまで画面外の iframe の読み込みを遅らせることができます。<iframe> の読み込み属性は Chrome 77 以降で利用可能で、他の Chromium ベースのブラウザにも導入されています。

<iframe src="https://example.com"
       loading="lazy"
       width="600"
       height="400">
</iframe>

読み込み属性では、次の値がサポートされます。

  • lazy: ブラウザで iframe の読み込みを遅らせることを示します。ブラウザは、ビューポートに近づくと iframe を読み込みます。iframe が遅延読み込みに適している場合に使用します。
  • eager: iframe をすぐに読み込みます。iframe が遅延読み込みに適さない場合に使用します。loading 属性が指定されていない場合は、これがデフォルトの動作です(ライトモードを除く)。
  • auto: このフレームを遅延読み込みするかどうかはブラウザが決定します。

loading 属性をサポートしていないブラウザではこの属性が無視されるため、ネイティブ遅延読み込みを段階的な機能強化として適用できます。この属性をサポートしているブラウザでは、ビューポートからの距離のしきい値(iframe の読み込みを開始する距離)の実装方法が異なる場合があります。

さまざまなタイプの埋め込みで iframe を遅延読み込みする方法をいくつか次に示します。

  • YouTube 動画: YouTube 動画プレーヤーの iframe を遅延読み込みするには、YouTube が提供する埋め込みコードに loading 属性を追加します。YouTube の埋め込みを遅延読み込みすると、最初のページ読み込み時に約 500 KB の容量を節約できます。
<iframe src="https://www.youtube.com/embed/aKydtOXW8mI"
   width="560" height="315"
   loading="lazy"
   title="YouTube video player"
   frameborder="0"
   allow="accelerometer; autoplay; clipboard-write;
            encrypted-media; gyroscope; picture-in-picture"
   allowfullscreen>
</iframe>
  • Google マップ: Google マップの iframe を遅延読み込みするには、Google Maps Embed API で生成される iframe 埋め込みのコードに loading 属性を含めます。Google Cloud API キーのプレースホルダがあるコードの例を次に示します。
<iframe src="https://www.google.com/maps/embed/v1/place?key=API_KEY&q=PLACE_ID"
   width="600" height="450"
   style="border:0;"
   allowfullscreen=""
   loading="lazy">
</iframe>

Lazysizes ライブラリ

ブラウザでは、iframe を読み込むタイミングを決定する際に、埋め込みのビューポートからの距離、有効な接続タイプやライトモードなどのシグナルも考慮されるため、ネイティブ遅延読み込みに一貫性がない可能性があります。距離のしきい値をより適切に制御する必要がある場合や、ブラウザ間で一貫した遅延読み込みエクスペリエンスを提供する場合は、lazysizes ライブラリを使用できます。

lazysizes は、画像と iframe の両方に対応した高速で SEO に適した遅延ローダーです。コンポーネントをダウンロードしたら、次のように YouTube 埋め込み用の iframe で使用できます。

<script src="lazysizes.min.js" async></script>

<iframe data-src="https://www.youtube.com/embed/aKydtOXW8mI"
   width="560" height="315"
   class="lazyload"
   title="YouTube video player"
   frameborder="0"
   allow="accelerometer; autoplay; clipboard-write;
        encrypted-media; gyroscope; picture-in-picture"
   allowfullscreen>
</iframe>

同様に、他のサードパーティの埋め込みの iframe でも Lazysize を使用できます。

なお、lazysizes は Intersection Observer API を使用して、要素が表示されるタイミングを検出します。

Facebook でデータ遅延を使用する

Facebook は、埋め込めるさまざまな種類のソーシャル プラグインを提供しています。投稿、コメント、動画、よく使われている [高評価] ボタンなどが表示されます。すべてのプラグインには data-lazy の設定が含まれています。true に設定すると、プラグインは loading="lazy" iframe 属性を設定して、ブラウザの遅延読み込みメカニズムを使用します。

Instagram フィードの遅延読み込み

Instagram には、埋め込みの一部としてマークアップのブロックとスクリプトが用意されています。このスクリプトは、ページに <iframe> を挿入します。この <iframe> を遅延読み込みすると、埋め込みのサイズが gzip で 100 KB を超える可能性があるため、パフォーマンスが向上します。WPZoomElfsight など、WordPress サイト用の多くの Instagram プラグインには、遅延読み込みオプションが用意されています。

埋め込みをファサードに置き換える

インタラクティブな埋め込みはページに付加価値をもたらしますが、多くのユーザーは操作しない可能性があります。たとえば、レストランのページを閲覧しているすべてのユーザーが、地図の埋め込みをクリック、展開、スクロール、ナビゲートするわけではありません。同様に、通信サービス プロバイダのページにアクセスしたすべてのユーザーが chatbot とやり取りするわけではありません。このような場合は、場所にファサードを表示することで、埋め込み全体の読み込みまたは遅延読み込みを回避できます。

ズームイン / ズームアウト機能を持つ地図の埋め込み。
地図の埋め込み
画像である地図のファサード。
地図のファサード

ファサードは、実際に埋め込まれたサードパーティに似た静的要素ですが、機能しないため、ページの読み込みにかかる負荷は大幅に軽減されます。ユーザーになんらかの価値を提供しながら、このような埋め込みを最適に読み込むための戦略は次のとおりです。

静止画像をファサードとして使用する

地図をインタラクティブにする必要がない場合は、地図の埋め込みの代わりに、静止画像を使用できます。地図上の関心のある地域にズームインして画像を撮影すると、インタラクティブな地図の埋め込みの代わりに、この画像を使用できます。以下に示すように、DevTools の [Capture node screenshot](ノードのスクリーンショットのキャプチャ)機能を使用して、埋め込まれた iframe 要素のスクリーンショットをキャプチャすることもできます。

ノードのスクリーンショットをキャプチャする

DevTools は画像を png としてキャプチャしますが、WebP format for better performance への変換を検討することもできます。

動的画像をファサードとして使用する

この方法では、インタラクティブな埋め込みに対応する画像を実行時に生成できます。以下に、静的なバージョンの埋め込みを生成できるツールをいくつか紹介します。

  • Maps Static API: Google の Maps Static API サービスは、標準の HTTP リクエストに含まれる URL パラメータに基づいて地図を生成し、ウェブページに表示できる画像として返します。この URL は、Google Maps API キーを含む必要があり、ページの <img> タグに src 属性として配置する必要があります。

    静的地図作成ツールを使用すると、URL に必要なパラメータを設定し、画像要素のコードをリアルタイムで確認できます。

    次のスニペットは、ソースが Maps Static API の URL に設定された画像のコードを示しています。画像をクリックすることで実際の地図にアクセスできるよう、リンクタグに含まれています。(注: API キー属性は URL に含まれません)

    <a href="https://www.google.com/maps/place/Albany,+NY/">
    <img src="https://maps.googleapis.com/maps/api/staticmap?center=Albany,+NY&zoom=13&scale=1&size=600x300&maptype=roadmap&format=png&visual_refresh=true" alt="Google Map of Albany, NY">
    </a>
    
  • Twitter のスクリーンショット: 地図のスクリーンショットと同様に、このコンセプトを使用すると、ライブフィードではなく Twitter のスクリーンショットを動的に埋め込むことができます。Tweetpik は、ツイートのスクリーンショットを撮るために使用できるツールの一つです。Tweetpik API はツイートの URL を受け取り、そのコンテンツを含む画像を返します。この API は、画像の背景、色、枠線、サイズをカスタマイズするためのパラメータも受け入れます。

クリックによる読み込みを使用してファサードを強化する

クリック読み込みのコンセプトは、遅延読み込みとファサードを組み合わせたものです。ページは最初にファサードで読み込まれます。ユーザーが静的プレースホルダをクリックして操作すると、サードパーティの埋め込みが読み込まれます。これは、インタラクション発生時のインポート パターンとも呼ばれ、次の手順で実装できます。

  1. ページの読み込み時: ファサードまたは静的要素がページに含まれます。
  2. マウスオーバー時: ファサードがサードパーティの埋め込みプロバイダに事前接続されます。
  3. クリック時: ファサードがサードパーティ製品に置き換わります。

ファサードは、動画プレーヤー、チャット ウィジェット、認証サービス、ソーシャル メディア ウィジェットのサードパーティ埋め込みで使用できます。YouTube 動画の埋め込みは、再生ボタン付きの単なる画像であり、よく見られるファサードです。実際の動画は、画像をクリックしたときにのみ読み込まれます。

インタラクション時のインポート パターンを使用して、カスタムの Click-to-Load ファサードを構築するか、さまざまなタイプの埋め込みで利用可能な次のオープンソース ファサードのいずれかを使用できます。

  • YouTube ファサード

    Lite-youtube-embed は YouTube プレーヤーに推奨されるファサードです。実際のプレーヤーのように見えますが、速度は 224 倍です。使用するには、スクリプトとスタイルシートをダウンロードし、HTML または JavaScript で <lite-youtube> タグを使用します。YouTube でサポートされているカスタム プレーヤー パラメータは、params 属性を使用して含めることができます。

    <lite-youtube videoid="ogfYd705cRs" playlabel="Play: Keynote (Google I/O '18)"></lite-youtube>
    

    lite-youtube-embed と実際の埋め込みの比較を以下に示します。

    ライト YouTube 埋め込み
    lite-YouTube 埋め込み
    実際の YouTube 埋め込み
    YouTube 埋め込み

    YouTube と Vimeo のプレーヤーが利用できる同様のファサードには、lite-youtubelite-vimeo-embedlite-vimeo があります。

  • チャット ウィジェットのファサード

    React-live-chat-loader は、埋め込みそのものではなく、チャット埋め込みのように見えるボタンを読み込みます。Intercom、Help Scout、Messenger など、さまざまなチャット プロバイダ プラットフォームで使用できます。類似ウィジェットはチャット ウィジェットよりも軽量で、読み込みが高速です。ユーザーがボタンにカーソルを合わせるかクリックした場合、またはページが長時間アイドル状態であった場合に、実際のチャット ウィジェットに置き換えられます。Postmark の事例紹介では、react-live-chat-loader の実装とパフォーマンスの改善について説明しています。

    Postmark チャット ウィジェット

一部のサードパーティの埋め込みで読み込みのパフォーマンスが低下し、上記のいずれの手法も使用できない場合は、その埋め込みを完全に削除するのが最も簡単な方法です。ユーザーが埋め込みのコンテンツにアクセスできるようにする場合は、target="_blank" を使用してそのコンテンツへのリンクを提供し、ユーザーがクリックして別のタブで表示できるようにします。

レイアウトの安定性

埋め込みコンテンツを動的に読み込むとページの読み込みパフォーマンスは向上しますが、ページ コンテンツの予期しない動きが生じることがあります。これはレイアウト シフトと呼ばれます。

スムーズなユーザー エクスペリエンスを保証するには視覚的な安定性が重要であるため、Cumulative Layout Shift(CLS)によって、こうしたシフトが発生する頻度と中断が測定されます。

レイアウト シフトは、後で動的に読み込まれる要素のためにページ読み込み時にスペースを確保することで回避できます。ブラウザは、要素の幅と高さを把握していれば、予約するスペースを決定できます。これを確実に行うには、iframe の width 属性と height 属性を指定するか、第三者の埋め込みを読み込む静的要素に固定サイズを設定します。たとえば、YouTube 埋め込み用の iframe では、幅と高さを次のように指定する必要があります。

<iframe src="https://www.youtube.com/embed/aKydtOXW8mI" width="560" height="315">
</iframe>

YouTube、Google マップ、Facebook などの一般的な埋め込みコードには、サイズ属性を指定した埋め込みコードがあります。ただし、これを提供しないプロバイダもあります。たとえば、このコード スニペットは結果の埋め込みのディメンションを示していません。

<a class="twitter-timeline" href="https://twitter.com/ChannelNewsAsia?ref_src=twsrc%5Etfw" data-tweet-limit="1">Tweets by ChannelNewsAsia</a>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

DevTools を使用して、このページのレンダリング後に挿入された iframe を検査できます。次のスニペットに示すように、挿入された iframe の高さは固定されていますが、幅はパーセンテージで指定します。

<iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true" class="twitter-timeline twitter-timeline-rendered" style="position: static; visibility: visible; display: inline-block; width: 100%; padding: 0px; border: none; max-width: 1000px; min-width: 180px; margin-top: 0px; margin-bottom: 0px; min-height: 200px; height: 6238.31px;" data-widget-id="profile:ChannelNewsAsia" title="Twitter Timeline">
</iframe>

この情報を使用して、フィードの読み込み時にコンテナが展開せず、レイアウト シフトが発生しないように、含まれる要素のサイズを設定できます。次のスニペットを使用すると、以前に含まれている埋め込みのサイズを修正できます。

<style>
    .twitterfeed { display: table-cell;  vertical-align: top; width: 100vw; }
    .twitter-timeline {height: 400px !important; }
</style>
<div class=twitterfeed>
       <a class="twitter-timeline" href="https://twitter.com/ChannelNewsAsia?ref_src=twsrc%5Etfw" data-tweet-limit="1">Tweets by ChannelNewsAsia</a>
       <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>

レイアウト シフト ターミネーター

サードパーティの埋め込みでは、最終的にレンダリングされるコンテンツの寸法(幅、高さ)が省略されることが多く、ページのレイアウトが大幅に変わる可能性があります。この問題に対処するには、DevTools を使用してさまざまなビューポート サイズで最終的なサイズを手動で検査する必要があります。

今回、自動化ツール Layout Shift Terminator がリリースされました。このツールを使用すると、Twitter や Facebook などのプロバイダから行われる一般的な埋め込みによるレイアウト シフトを減らすことができます。

Layout Shift Terminator:

  • クライアントサイドの埋め込みを iframe に読み込みます。
  • iframe のサイズを一般的なビューポートのサイズに変更します。
  • よく使用される各ビューポートについて、埋め込みのディメンションをキャプチャして、後でメディアクエリとコンテナクエリを生成します。
  • 埋め込みが初期化されるまで(その後 min-height のスタイルが削除されるまで)、メディアクエリ(およびコンテナクエリ)を使用して、埋め込みマークアップの周囲の min-height ラッパーのサイズを調整します。
  • 最適化された埋め込みスニペットを生成します。このスニペットは、ページ内の埋め込みコードを挿入する場所にコピーして貼り付けることができます。

    シフトターミナル

ぜひ Layout Shift Terminator をお試しください。フィードバックがございましたら、GitHub にお気軽にお送りください。このツールは現在ベータ版であり、時間の経過とともにさらに改良が加えられ、改善される予定です。

おわりに

サードパーティの埋め込みはユーザーに多くの価値をもたらしますが、ページ内の埋め込みの数とサイズが大きくなると、パフォーマンスが低下する可能性があります。そのため、位置、関連性、潜在的なユーザーのニーズに基づいて、埋め込みについて適切な読み込み戦略を測定、判断、使用する必要があります。