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

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

Katie Hempenius
Katie Hempenius
Leena Sohoni
Leena Sohoni

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

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

埋め込みとは

サードパーティの埋め込みとは、サイトに表示されるコンテンツのうち、次のいずれかに該当するものです。

  • 自分が作成したものではない
  • サードパーティ サーバーから配信される

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

埋め込みは、次のような用途でよく使用されます。

  • スポーツ、ニュース、エンターテイメント、ファッション関連のウェブサイトでは、テキスト コンテンツを補完するために動画が使用されています。
  • Twitter やソーシャル メディアのアカウントを運用している組織は、これらのアカウントのフィードをウェブページに埋め込んで、より多くのユーザーにアプローチしています。
  • レストラン、公園、イベント会場のページには、地図が埋め込まれていることがよくあります。

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

サードパーティの埋め込みがパフォーマンスに与える影響

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

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

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

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> の読み込み属性は、すべての最新ブラウザで使用できます。

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

loading 属性は次の値をサポートしています。

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

loading 属性をサポートしていないブラウザはこれを無視するため、ブラウザレベルの遅延読み込みをプログレッシブ エンハンスメントとして適用できます。この属性をサポートするブラウザでは、distance-from-viewport のしきい値(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>

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

lazysizes は Intersection Observer API を使用して要素が可視になったタイミングを検出します。

Facebook での data-lazy の使用

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

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

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

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

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

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

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

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

地図をインタラクティブにする必要がない場合は、地図の埋め込みの代わりに静止画像を使用できます。地図上の関心のあるエリアを拡大して画像をキャプチャし、インタラクティブ マップの埋め込みの代わりに使用できます。DevTools の [ノードのスクリーンショットをキャプチャ] 機能を使用して、埋め込み iframe 要素のスクリーンショットをキャプチャすることもできます。

HTML エディタのコンテキスト メニューでハイライト表示されている [ノードのスクリーンショットをキャプチャ] オプション。

DevTools は画像を png としてキャプチャしますが、パフォーマンスを向上させるために WebP 形式に変換することも検討してください。

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

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

  • 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 は、ツイートのスクリーンショットを撮影するために使用できるツールの 1 つです。Tweetpik API はツイートの URL を受け取り、その内容を含む画像を返します。API は、画像の背景、色、枠線、寸法をカスタマイズするためのパラメータも受け入れます。

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

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

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

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

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

  • 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 と実際の埋め込みを比較します。

    Lite YouTube 埋め込み
    軽量版の YouTube 埋め込み
    実際の YouTube 埋め込み
    YouTube 埋め込み

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

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

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

    パッケージ化されたコードを表示する HTML エディタの 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 を使用して最終的なサイズを手動で検査しないと、解決が難しい場合があります。

レイアウト シフト ターミネーターという自動化ツールを使用すると、Twitter や Facebook などの一般的なプロバイダの埋め込みによるレイアウト シフトを減らすことができます。

レイアウト シフトの終了:

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

    コード出力とプレビューを表示するレイアウト シフト ターミネーター。

レイアウト シフト ターミネーターをお試しいただき、ご意見やご感想がございましたら、レイアウト シフト ターミネーターの GitHub プロジェクトにお寄せください。このツールはベータ版であり、今後さらに改良を重ねていく予定です。

まとめ

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