📽️

Lite YouTube Embedの遅延読み込みで遅いyoutube動画の表示速度を224倍速くする

2021/06/16に公開

今回は、youtube動画をLite YouTube Embedを使ってパフォーマンス改善する方法に関して書きます。
解説や引用文献に関して改善点があればコメントをお待ちしております。

背景

youtube動画は、Webパフォーマンスに大きな影響を与えます。

youtube動画を表示する一連の流れで、様々なJavaScriptを呼び出しているため、Page Speed Insightでは下記のように注意をされます。

Lite YouTube Embedとは?

Lite YouTube Embedは、Google Developerでも紹介されているライブラリの1つです。

処理は下記流れで実行されます。

  • youtube動画を読み込む代わりに、画像を表示する。
  • 画像にmouseoverしたら、preconnectsで先読みする。
  • 画像をクリックしたら、youtube動画を表示&再生をする。

youtube動画を読み込む代わりに、画像を表示する。

画像はYoutube側が提供している機能を使って、自動で取得します。

src/lite-yt-embed.js
if (!this.style.backgroundImage) {
  this.posterUrl = `https://i.ytimg.com/vi/${this.videoId}/hqdefault.jpg`;
  // Warm the connection for the poster image
  LiteYTEmbed.addPrefetch('preload', this.posterUrl, 'image');

  this.style.backgroundImage = `url("${this.posterUrl}")`;
}

youtubeの動画は下記のようなURLになっています。

https://www.youtube.com/watch?v=ogfYd705cRs&t=4s

?v=ogfYd705cRsの値を使って、https://i.ytimg.com/vi/${this.videoId}/hqdefault.jpgのように指定すると、自動で動画からサムネイルを取得してくれます。

例:https://i.ytimg.com/vi/ogfYd705cRs/hqdefault.jpg

hqdefault.jpgは高画質版です。
指定を変えることによって、他の画質、サイズへ変えることができます。

画像にmouseoverしたら、preconnectsで先読みする。

// On hover (or tap), warm up the TCP connections we're (likely) about to use.
this.addEventListener('pointerover', LiteYTEmbed.warmConnections, {once: true});

pointeroverイベントは、ポインティングデバイスが要素のヒットテスト境界内に移動したときに発生します。

static warmConnections() {
    if (LiteYTEmbed.preconnected) return;

    // The iframe document and most of its subresources come right off youtube.com
    LiteYTEmbed.addPrefetch('preconnect', 'https://www.youtube-nocookie.com');
    // The botguard script is fetched off from google.com
    LiteYTEmbed.addPrefetch('preconnect', 'https://www.google.com');

    // Not certain if these ad related domains are in the critical path. Could verify with domain-specific throttling.
    LiteYTEmbed.addPrefetch('preconnect', 'https://googleads.g.doubleclick.net');
    LiteYTEmbed.addPrefetch('preconnect', 'https://static.doubleclick.net');

    LiteYTEmbed.preconnected = true;
}

Preconnectは、Resource Hintsの1つです、
dns lookupやTCP connectionを実行します。

ここでは、将来的に発生する「youtube.com」などへのリクエストをhoverやタップしたタイミングで、preconnectすることによって、クリックした時の表示速度を向上させています。

画像をクリックしたら、youtube動画を表示&再生をする。

this.addEventListener('click', e => this.addIframe());

addIframe()が実行されることによって、youtube動画のiframeが生成され、実行されます。

実装する上での懸念点

実装する上での懸念点は下記になります。

  • 画質や表示が変わる。
  • SPや特定のブラウザでは2回クリックする必要が生じる。

画質や表示が変わる。

本ライブラリでは、画像は自動で生成されます。

CSSでアイコンを付け加えていますが、本来の表示とは若干異なります。

自動生成したサムネイル 本来の表示

また、高画質版などの選択はできますが、高画質版のhqdefault.jpgでもデフォルトの表示に比べると画質が落ちる場合があります。

その場合は、HTMLであらかじめ用意した画像を使うことによって、対応することができます。

SPや特定のブラウザでは2回クリックする必要が生じる。

特定の環境では、動画を再生するまで2回クリックが必要な場合があります。

params.append('autoplay', '1');

autoplayパラメータが「1」に設定されているため、プレーヤーが読み込まれると、動画は自動的に再生されます。

しかし、こちらのissueにあるように特定の条件下では2回クリックする必要があります。

参考

Discussion