pagespeedinsightsで『レンダリングを妨げるリソースの除外』する #4
カトウ
YOUTUBEの埋め込みコードを遅延ロードする
YOUTUBEの埋め込みコードを使用しているページで、『第三者コードの影響を抑えてください』を解消する方法を紹介します。
YOUTUBEの埋め込みコードを使用しているページで、『第三者コードの影響を抑えてください』を解消する方法を紹介します。
やりたいこと
・再生ボタンが押されるまで<iframe>を読み込まない
・<iframe>を読み込むまでサムネイル画像を表示する
おまけ
・YOUTUBE以外(再生ボタンが無い)の<iframe>を遅延ロードさせる
デフォルト
HTML
<div class="iframe-content">
<iframe width="560" height="315" data-src="https://www.youtube.com/embed/vc7LlUtQgNw" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
遅延ロード
<iframe>の[src]を空にしておき、再生ボタンが押されると、[data-src]の内容を[src]に入れ、読み込みを開始します。
また、再生ボタンが押されるまで、ページに何も表示されないので、代わりのサムネイル画像と再生ボタンを前面に表示しています。
読み込みが始まると、<iframe>を前面に表示し、IFrame Player APIを使って再生を開始します。
おまけで、YOUTUBE以外の<iframe>だった場合は、[data-src]の内容を[src]に入れ、読み込みを開始します。
HTML
// YOUTUBEの埋め込みコード
<div class="iframe-content">
<div class="lazy-iframe">
// IFrame Player API で再生できるよう『enablejsapi=1』を追加してください
<iframe loading="lazy" id="iframe-0" width="560" height="315" data-src="https://www.youtube.com/embed/vc7LlUtQgNw?enablejsapi=1" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<img loading="lazy" src="https://img.youtube.com/vi/vc7LlUtQgNw/maxresdefault.jpg" width="560" height="315" />
<button class="play-btn" type="button">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 512 341.6" xml:space="preserve" class="play-btn-icon"><g>
<path class="st0" d="M453,332.8c-131.3,11.8-262.6,11.8-394,0c-24.4-2.2-44.3-20.4-48.6-44.5c-13.9-78.7-13.9-156.4,0-235 C14.7,29.2,34.7,11,59,8.8c131.3-11.8,262.6-11.8,394,0c24.4,2.2,44.3,20.4,48.6,44.5c13.9,78.7,13.9,156.4,0,235 C497.3,312.4,477.3,330.6,453,332.8z"></path>
<path class="st1" d="M335,158.3L222,93c-5.9-3.4-13.3,0.9-13.3,7.7v130.5c0,6.8,7.4,11.1,13.3,7.7l113-65.2 C340.9,170.3,340.9,161.7,335,158.3z"></path>
</g></svg>
</button>
</div>
</div>
// その他のiframe
<div class="iframe-content">
<div class="lazy-iframe">
<iframe loading="lazy" id="iframe-1" width="560" height="315" data-src="https://example.zukoo.net/iframe-contents/" frameborder="0"></iframe>
</div>
</div>
CSS
// <iframe>と<img>のサイズを親要素に合わせる
.iframe-content {
position: relative;
width: 100%;
padding: 56.25% 0 0 0;
}
.iframe-content iframe ,
.iframe-content img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.iframe-content img {
object-fit: cover;
}
// 再生ボタンのスタイル
.play-btn {
width: 64px;
height: 43px;
background-color: transparent;
border: none;
cursor: pointer;
outline: none;
padding: 0;
appearance: none;
}
.play-btn-icon {
width: 64px;
height: 43px;
transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1);
}
.play-btn-icon .st0 {
fill: #212121;
fill-opacity: .8;
}
.play-btn-icon .st1 {
fill: #ffffff;
fill-opacity: 1;
}
// <button>の上にマウスがあるとき、再生ボタンを赤くする
.play-btn-icon:hover .play-btn-icon .st0 {
fill: #ff0000;
fill-opacity: 1;
}
// 遅延ロードする<iframe>の上にサムネイルと再生ボタンを重ねる
.lazy-iframe {
cursor: pointer;
}
.lazy-iframe img {
z-index: 10;
}
// サムネイルのどこでもクリックできるよう、親要素のサイズに合わせる
.lazy-iframe .play-btn {
position: absolute;
z-index: 20;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
// 再生ボタンを上下左右中央に配置する
.lazy-iframe .play-btn-icon {
position: absolute;
z-index: 30;
top: 50%;
left: 50%;
margin-left: -32px;
margin-top: -21px;
}
// 再生ボタンが押された後は、<iframe>を前面に表示する
.iframe-content .lazy-iframe.is-active iframe {
z-index: 100;
}
JS
(function(window,document){
var lazyIframe=document.querySelectorAll('.lazy-iframe');
var lazyYoutube=[];
var isYoutube=false;
function _onYoutube(e){
e.preventDefault();
var _this=this;
_this._inPlayBtn.removeEventListener('touchstart',_onYoutube);
_this._inPlayBtn.removeEventListener('click',_onYoutube);
_this._inIframe.setAttribute('src',_this._inIframe.dataset.src);
var youtubePlayer=new YT.Player(_this._inIframe.getAttribute('id'),{
events:{
'onReady':function(e){
e.target.mute(); // 勝手に音が出ないようミュートにしています
e.target.playVideo();
_this._lazyYoutube.classList.add('is-active');
}
}
});
}
function _youtubeApiIni(){
// 『JavaScriptを遅延ロードする』で紹介した関数を使用しています
// https://www.zukoo.net/blog/detail.html?id=269
window.lazyScriptLib.insertScript('https://www.youtube.com/iframe_api',function(){
window.YT.ready(function(){
for(var i=0,l=lazyYoutube.length;i<l;i++){
var _lazyYoutube=lazyYoutube[i];
var _inIframe=_lazyYoutube.querySelector('iframe');
var _inPlayBtn=_lazyYoutube.querySelector('.play-btn');
_inPlayBtn.addEventListener('touchstart',{
'_lazyYoutube':_lazyYoutube,
'_inIframe':_inIframe,
'_inPlayBtn':_inPlayBtn,
'handleEvent':_onYoutube
});
_inPlayBtn.addEventListener('click',{
'_lazyYoutube':_lazyYoutube,
'_inIframe':_inIframe,
'_inPlayBtn':_inPlayBtn,
'handleEvent':_onYoutube
});
}
});
});
}
for(var i=0,l=lazyIframe.length;i<l;i++){
var _lazyIframe=lazyIframe[i];
var _inIframe=_lazyIframe.querySelector('iframe');
var _inPlayBtn=_lazyIframe.querySelector('.play-btn');
if(_inPlayBtn!==null){
isYoutube=true;
lazyYoutube.push(_lazyIframe);
}else{
// 再生ボタンが無い場合は、読み込みを開始します
_inIframe.setAttribute('src',_inIframe.dataset.src);
_lazyIframe.classList.add('is-active');
}
}
if(isYoutube){
_youtubeApiIni();
}
})(window,document);