Google(web.dev) による iframe 埋め込みのベストプラクティス

投稿: 2021年10月07日
タグ: 
  Web  ニュースネタ

Google の Developer 向けサイトである web.dev で Webサイトでの埋め込みに関するベストプラクティス記事が投稿されました。

Best practices for using third-party embeds
https://web.dev/embed-best-practices/open_in_new

埋め込み、とは外部サイトのコンテンツのことを指しており、一般的には iframe タグで読み込まれます。 上記の記事でも iframe タグで読み込まれる JavaScript を前提に、パフォーマンスとレイアウトに関して解説されています。

  • Google の Developer 向けサイトで外部サイトのコンテンツ埋め込みに関するベストプラクティス記事が投稿された
  • パフォーマンス対策とレイアウト崩れ対策に関するベストプラクティス
  • パフォーマンス対策は、非同期読み込み(async/defer) と遅延読み込み(lazy loading)
  • パフォーマンス遅延への対策1: async / defer による非同期読み込み

    1点目に挙げられているのは、とても一般的な話ですが、外部サイトのコンテンツの読み込みによって自分の Webサイトの読み込みが待機させられるのを回避するために script タグに async か defer を入れて非同期読み込みにしましょう、という点です。

    <script src="https://example.com/3p-library.js" async></script>

    本サイトでも Twitter ボタンやはてなブックマークボタンを貼っていますが、async で読み込んでいます。 ユーザーから見ると Webサイト表示後に Twitter ボタンが遅れて表示されることも多々ありますが、ボタン表示を待って Webサイトのロード自体が遅延することは回避した方がよいので必須の対応かと思います。

    パフォーマンス遅延への対策2: iframe 遅延読み込み

    async/defer という誰でもやってるレベルから比べると一気にレベルがあがりました。
    iframe の loading 属性で Webページ描画時には iframe を読み込まず、 ブラウザ上の特定の位置(viewport からの距離) までスクロールされたら読み込む対策です。

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

    スクロールしないと見えない iframe ということは『ユーザーに対するパフォーマンス対策』というよりは Webサイトとしての効率化に該当すると思いますが、 ユーザーが見ないかもしれないのに大容量の Script を読み込む可能性があるのであればやった方がよさそうです。

    ただ、iframe の loading 属性は まだ実験的(Experimental) な機能の扱いで、Chromium ベースのブラウザ(Chrome、Edgeなど) でのみ利用可能で、 Firefox、Safari は 2021年10月段階では利用可能になっていません。

    Youtube の遅延読み込みで 約500KB の節約

    Youtube 動画を iframe で埋め込む場合、前述の iframe の loading="lazy" を指定すると、最初のWebサイト読み込みで約500KB 読み込まずにすむとのことです。
    ページの途中に何個も Youtube動画が埋め込まれているサイトというのはたまに見るので、これをやってくれると Chrome で無駄な読み取りをしなくてよくなることになります。

    web.dev の記事では Youtube動画以外にも、Google Maps への遅延読み取りや、 lazysizes というライブラリを使った Facebook、Instagram の遅延読み込みについて記載されています。

    パフォーマンスへの対策3: 地図などのインタラクティブな要素を静止画像に

    操作可能なコンテンツが埋め込まれているサイトも多いですが、『多くのユーザーはそれを操作しない可能性がある』と web.dev の記事では記載されています。実際そうでしょう。 操作されないのに動的コンテンツを取得させるのは非効率なので、静止画像に置き換える方法が提示されています。

    Google Maps の場合、Google Maps Static API というサービスで指定した場所の画像を取得できるようになっているそうです。 もちろん、ユーザーが操作したい際(静止画像にマウスオーバーした時点) には透過的に地図が操作できるような実装にはする必要はあります。

    Google Maps - Maps Static API
    https://developers.google.com/maps/documentation/maps-static/overviewopen_in_new

    また、Twitter も tweetpik でスクリーンショットを撮って、それに置き換えるとよいと記載されています。

    tweetpik
    https://tweetpik.com/open_in_new

    レイアウト崩れへの対策: iframe に width、height を指定

    外部サイトのコンテンツのロードによるレイアウト崩れはよくある問題かと思います。 外部サイトの iframe (例えば Twitter) を読み込んだことで 他のコンテンツが下に下がってしまったりボタンの位置が変わったりすると対策が必要になる場合もあると思います。

    web.dev の記事ではレイアウトが崩れないように width、height を指定するという一般的な対策は書きつつ、動的コンテンツはそれ(width/height が一定でない) が難しいことも言及されています。 対応の 1つとして Chrome Labs で開発している Layout Shift Terminator という自動化ツールが挙げられていました。

    Layout Shift Terminator
    https://googlechromelabs.github.io/layout-shift-terminator/open_in_new
    GitHub - Layout Shift Terminator
    https://github.com/GoogleChromeLabs/layout-shift-terminatoropen_in_new
    iframe の loading 属性は Safari や Firefox でも採用されて、既定になると良さそうです。(調べてないので何かサイドエフェクトがあって まだ組み込まれていないのかもしれません)
    後、Twitter 埋め込みの読み込みは本当に遅いので、tweetpik で代替するのはとても良さそうです。