埋め込みyoutubeが想像以上に戦犯級だった件
posted : 2018.05.06
2019/1/11 記事内容を大幅に加筆・修正しました。
こんにちわ、ma-ya’s CREATE[まーやずくりえいと]です。
youtubeの埋め込み動画をサイトに設置したいときありますよね。
そんな時は簡単です。見たい動画のページから埋め込みコードを取得してソースに張り付けるだけ。
簡単ですね、ではさようなら。
と、そうは問屋が卸しません。
youtubeの埋め込みはたとえ一つでもサイトに大きな悪影響を及ぼすことがある?
そうなんです。ざっくりと箇条書きにすると
- 埋め込みyoutubeの読込中はサイトの動きが止まるor瞬断される
- サイトのレイアウトが一瞬狂うことがある
- そもそも読込処理が重い
- たまにコンソールでエラーが出る
- サイト評価がすんごい下がる
※上記はいずれもブラウザ未キャッシュ時の挙動、そして可能性の話です。あしからず。
ブログなどの投稿ページだったらもうどんどん貼っちゃっていいと思います。
単純にその投稿ページが重くなるだけだから(無責任)。
では埋め込むのがトップページだったらどうでしょう。
サイトの入り口となるページで問題が発生するのは極力抑えたいです。
↑の①や②はサイトによっては起こらないor気にならない程度だと思いますが、④はGTmetrixでかなり差が出ました。
その差なんと14ポイント。
- youtubeを普通に埋め込んだ状態が83点(%)
- youtubeを外した状態が92点(%)
ええっそんなに????!
と思うかもしれませんがこれは事実です。。
まあそもそもGTmetrixの信憑性がどうなんだという話もありますが、何事も勉強ということで制作中のサイトで対処してみました。
そして盛大にハマりました(爆)。
サイトの構成的にやりづらい面もあったんですが丸二日掛けてあーでもないこーでもない言いながら何とか現状では解決。
方法はざっくり言うと2パターンです。
- 動画の遅延読込
→HTMLレンダリング時にはiframe(動画読込)をスルー、画像含むページ全体が読み込まれた後にiframe読み込み - そもそも動画を読み込まずに代替画像を表示しておく
→youtube動画のサムネイルを表示しておき、クリックでiframeを読み込む
よりベターなのは、そもそも動画の読み込みをせず、読み込むかどうかはユーザーのクリックに委ねる②の方法でしょうか。
ちなみに以降のサンプルは複数の動画読込にも対応しています(単体でもOK)。
方法①:iframe動画の遅延読み込み
※動画下にある画像は読込に時間がかかる要素(ビッグデータ)を想定した画像です。
※サンドウィッチマンが好きです。
解説
HTML
iframeに任意のclassをつけ、「src」を「data-src」に書き換えます。
こうすることでsrc属性が無くなるので、HTMLレンダリング中は動画の読み込みがスルーされます。
<iframe class="youtube" data-src="https://www.youtube.com/embed/~"~></iframe>
Javascript
下記をHTMLに記述するなり、外部ファイルとして読み込むなりして下さい。
基本的にはどこに記述しても動くハズですが、まあ無難にbody閉じタグ直前あたりで。
こだわりが無ければcodepenのHTMLをまるっとコピーでもいいです。
ぼくの場合、これだけでもだいぶ改善されました。
流れとしては、
- 任意のクラス名(ここでは”youtube”)を付けたiframeを取得
- そのiframeに「data-src」属性があったら
- 「data-src」の値(URL)をsrc属性の値にセットする
- ①~③の処理をload後(画像含むページ全体の読み込み後)に実行
という感じでしょうか。
ブラウザのキャッシュ削除→リロードでサンプルのcodepenを見ると、画像表示後に動画が表示されるのがわかると思います。
制作中のサイトではページの初回読み込み時(ブラウザ未キャッシュ時)だけ、たまに微妙なレイアウト崩れが起きました。
リロードすれば治るし気にならないっちゃ気にならないんですが、一旦見つけるとやっぱ気になる。。
根本原因はわからないんですが、上記コードを付加することで微妙なレイアウト崩れが改善。
そしてサイト評価はなんと92ポイントに。
重い処理を後回しにすることでサイト評価も上がるというわけですね。ふむふむ。
これで終わりでも良かったんですが、さらに別の方法も試してみました。
方法②:そもそも動画読込無しで代替画像を表示しておく
サイト上ではJavaScript制御でSVGアニメーションやスクロールイベントを結構使っているんですが、その挙動が動画を読み込む瞬間にカクつくんですよね。これも気にならないっちゃ気にならないんですが。
JavaScriptはシングルスレッド、というのはぼんやり知っていたんですが、その辺りも絡んでくるのかな~とか思いつつ、もういっそ動画の読み込みはしないで代替画像を表示しとけばいいんじゃないかと考えました。
ユーザーの代替画像クリックで初めて動画が読み込まれる仕様なので、なんつーか、エコですよね(意味不)。
※画像クリックで動画が読み込まれます。
※サンドウィッチマンが好きです。
解説
HTML
<div class="youtube"> <iframe data-src="https://www.youtube.com/embed/~"~></iframe> </div>
方法②ではiframeを任意のクラスを付与した要素で囲ってやります。
サンプルはdivですが他の要素でも問題なし。
srcをdata-srcに変更するのは方法①と変わりません。
Javascript
少し処理が複雑になったのでjQueryを使っています。
ので、上記の通りスクリプト本体の前でjQueryを読み込んでください。
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
既にサイトでjQueryを使っている場合↑は不要です。
んで、8行目の
<img src="http://img.youtube.com/vi/'+id+'/mqdefault.jpg" />
の部分ですが、ここでyoutube動画のサムネイル画像を取得しています。
youtubeの動画ID(11桁)さえわかれば色々なサイズの動画サムネイルが取得できるので便利です。
詳しくは↓のサイト様をご参考あれ。
複数動画の埋め込み時に効果を発揮。サイト評価も改善!
これで完璧なハズ!と期待を込めて検証したところ何とか(運良く?)改善してました。
今回採用したのは方法②です。
方法①に比べて動画自体の読み込みが初期表示時に行われない為、複数動画の埋め込み時は特に効果を発揮します。
そして改めてGTmetrixで計測したところなななんと評価は97ポイントに。
youtube外した時より良くなってる。。
ベストプラクティスとは言い切れませんが、あながち見当違いでもないんでしょうか。
これを教訓にyoutube埋め込みには気を付けよう。。
にしてもこの二日間、いつもより多めにググって色んなサイトを参考にさせて頂きました。
本日もコーディングの先人達に感謝。
サイトの評価(ポイント)について
サイト間や計測タイミングでかなりバラつきが出ると思うので、劇的なポイント向上の約束は出来かねます。あしからず。