【Defer.js】SNS の埋め込み数が多い場合の対応方法
Twitter や Instagram などの投稿をブログ記事に埋め込む場合、Defer.js を使ってスクリプトを遅延読み込みすることでページ表示の高速化を図ることができます。
ただ、埋め込み数が多い場合、スクリプト読み込み後の表示処理に時間がかかり、ページの動きが重くなってしまうことがあります。
※ 特にモバイルで閲覧する場合。PC では体感的にはほとんど問題なし
こういう場合は Defer.js の適用方法を少し変えることで、ページ動作の重さを大幅に改善することができます。ページスピードのスコアももちろん◎。
Defer.js 作者の Shin さんにご提供いただいたコードとともに適用方法を紹介します。
基本の Defer.js 対応方法は以下の記事にてまとめています。
目次
埋め込み数が多い場合の Defer.js 対応
以前紹介した基本の対応方法の場合、スクリプトの遅延読み込み後、ページ内のすべての埋め込み画像の表示処理が一斉に走ります。
埋め込み数が少ない場合は、基本の方法でもページの動作に影響を与えることは少ないと思うので問題はないと思います。
ただ、埋め込み数が多くなると、一斉に表示処理が行われることで一時的にページが重くなってしまう場合があります。
私が使っている iPhone 6s は8年前の古いものですが、埋め込みの多いページで SNS のスクリプトの読み込みが始まると、画面が一瞬固まって目次をクリックしてもリンクに飛ばなかったり、スクロールが固まったり、スクロールしてもコンテンツが表示されなくなったりということが起きていました。これはかなりのストレスです。(古いスマホを使っている一部のユーザーにしか起きないかもしれませんが)
この記事で紹介する方法は、スクリプトの遅延読み込み後、SNS の埋め込み位置までスクロールしたときに初めて表示処理を行うというものです。
スクロールするにつれて1つずつ画像が表示処理されるため、スクリプト読み込み後に一気に重くなるような瞬間がなく、私の iPhone ではページ上の動作が劇的に改善されました。
以下の記事は、本記事の方法で記事内に40個以上の投稿を埋め込んでいます。表示動作の参考にしてください。
2023年F1イケメン現役ドライバーTOP6!彼女もまとめました。
埋め込みが大量になってしまうのは、芸能人やスポーツ選手など有名人の顔写真は本人の公式 SNS アカウントの引用でしか掲載が認められないため。
以前、有名人画像をブログのサーバーにアップして掲載してしまっていたところ、アフィリエイト ASP より「知的所有権侵害に該当するサイト」とされて申請を拒否されたことがあります。
※追記:Defer.js 適用のデモページを作成しました。
デモ①が基本の対応方法、デモ②③が本記事で紹介している方法です。
demo by Limosuki
基本の方法にするか、本記事の方法にするかは、埋め込みの数やページ動作が重いかどうかでご検討ください。
Defer.js の適用手順
1.defer.js を head タグ内に設置
defer.js を設置します。
shinsenter/defer.js · GitHub
以下をテンプレートの<head>
~</head>
の間に設置してください。
<script src="https://cdn.jsdelivr.net/npm/@shinsenter/defer.js@3.5.0/dist/defer.min.js"></script>
@3.5.0
の部分はバージョンなので、念のため上記公式ページで最新版を確認の上でご使用ください。
<body>
内に設置しても動くようですが、公式説明では<head>
内に設置となっています。自己判断で<body>
内に設置しても良いかとは思います。
※ JetTheme を利用中の場合は、すでにテンプレートに組み込まれているため設置は不要です。
2./body タグ直前に、遅延読み込み用コードを設置
テンプレートの</body>
直前に以下のコードを設置します。
const twitterLazy = document.getElementsByClassName('lazy-tweet');
const instaLazy = document.getElementsByClassName('lazy-instagram');
try {
if (twitterLazy.length !== 0) {
Defer.js('https://platform.twitter.com/widgets.js', 'twitter-sdk', 1000, function() {
Defer.dom('.lazy-tweet', 0, 'twitter-loaded', function(node) {
node.className = 'twitter-tweet';
twttr.widgets.load(node.parentNode);
console.info('Twitter post is loaded.'); // debug
}, {rootMargin: "120%"});
});
}
if (instaLazy.length !== 0) {
Defer.js('https://www.instagram.com/embed.js', 'instagram-sdk', 1000, function() {
Defer.dom('.lazy-instagram', 0, 'instagram-loaded', function(node) {
node.className = 'instagram-media';
instgrm.Embeds.process(node.parentNode);
console.info('Instagram post is loaded.'); // debug
}, {rootMargin: "120%"});
});
}
} catch (error) {
console.log(error);
}
※ JetTheme を利用中の場合は、/*Your Script is here to maintain performance.*/
の下に設置してください。
※ 他のテンプレートの場合は、上記コードを次のように囲んで設置してください。
<script>/*<![CDATA[*/
遅延読み込み用コード
/*]]>*/</script>
1000
の部分は、スクリプト読み込みの遅延秒数(ミリ秒単位)です。
{rootMargin: "120%"}
の部分は、どのタイミングで埋め込みを表示するかを指示する数値です。120%の場合、画面の120%の領域に埋め込みが現れたときに表示処理が開始されます。
私は120%だと少しタイミングが遅いと感じたので、200%に設定して利用しています。
(数値を大きくするほど、画面の手前で表示処理が行われることになります)
120%と200%の違いはデモページをご参照ください。
このコードは、Defer.js というスクリプトの遅延機能と、Defer.dom という表示の遅延機能を組み合わせたものになっています。
Defer.dom 機能では、画像や YouTube などの iframe を遅延させることもできます。詳細は公式ドキュメントか、以前の基本対応の記事後半をご参照ください。
今回紹介したコードは Defer.js の開発中ドキュメントに記載されているものをベースにさせていただきました。
GitHub - shinsenter/defer.js at develop
Shin さんありがとう!
3.埋め込みコードのクラスを書き換える
公式埋め込みコードのクラスを次のように書き換えます。
- Twitter の場合:
twitter-tweet
→lazy-tweet
- Instagram の場合:
instagram-media
→lazy-instagram
この書き換えを行わないと、上記コードは適用されません。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Another day in desert…<br><br>昨日はオマーンで撮影がありました! <a href="https://t.co/qir274Trz6">pic.twitter.com/qir274Trz6</a></p>— 角田裕毅/Yuki Tsunoda (@yukitsunoda07) <a href="https://twitter.com/yukitsunoda07/status/1630573555330043905?ref_src=twsrc%5Etfw">February 28, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="lazy-tweet"><p lang="ja" dir="ltr">Another day in desert…<br><br>昨日はオマーンで撮影がありました! <a href="https://t.co/qir274Trz6">pic.twitter.com/qir274Trz6</a></p>— 角田裕毅/Yuki Tsunoda (@yukitsunoda07) <a href="https://twitter.com/yukitsunoda07/status/1630573555330043905?ref_src=twsrc%5Etfw">February 28, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="instagram-media" data-instgrm-permalink="https://www.instagram.com/p/CpI3ZVss6sB/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="14"
...略...
PIERRE GASLY 🇫🇷(@pierregasly)がシェアした投稿</a></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script>
<blockquote class="lazy-instagram" data-instgrm-permalink="https://www.instagram.com/p/CpI3ZVss6sB/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="14"
...略...
PIERRE GASLY 🇫🇷(@pierregasly)がシェアした投稿</a></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script>
4.埋め込みコードから script タグを削除
埋め込みコードから<script>タグを削除したうえで記事に埋め込みます。
<script>
タグは、公式埋め込みコードの末尾にあります。
<blockquote class="lazy-tweet"><p lang="ja" dir="ltr">Another day in desert…<br><br>昨日はオマーンで撮影がありました! <a href="https://t.co/qir274Trz6">pic.twitter.com/qir274Trz6</a></p>— 角田裕毅/Yuki Tsunoda (@yukitsunoda07) <a href="https://twitter.com/yukitsunoda07/status/1630573555330043905?ref_src=twsrc%5Etfw">February 28, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> ←ここを削除
<blockquote class="lazy-tweet"><p lang="ja" dir="ltr">Another day in desert…<br><br>昨日はオマーンで撮影がありました! <a href="https://t.co/qir274Trz6">pic.twitter.com/qir274Trz6</a></p>— 角田裕毅/Yuki Tsunoda (@yukitsunoda07) <a href="https://twitter.com/yukitsunoda07/status/1630573555330043905?ref_src=twsrc%5Etfw">February 28, 2023</a></blockquote>
<blockquote class="lazy-instagram" data-instgrm-permalink="https://www.instagram.com/p/CpI3ZVss6sB/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="14"
...略...
PIERRE GASLY 🇫🇷(@pierregasly)がシェアした投稿</a></p></div></blockquote> <script async src="//www.instagram.com/embed.js"></script> ←ここを削除
<blockquote class="lazy-instagram" data-instgrm-permalink="https://www.instagram.com/p/CpI3ZVss6sB/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="14"
...略...
PIERRE GASLY 🇫🇷(@pierregasly)がシェアした投稿</a></p></div></blockquote>
これで埋め込み画像の遅延表示ができているはずです!
検証ツールのネットワークタブを見ると、1つずつ読み込まれていることがわかると思います。
動作確認をしたうえでご利用ください。
Defer.js 基本の対応方法