Twitter Instagram 埋め込みをスクロールで遅延読み込み
複数の「Twitter / Instagram」埋め込み要素を、スクロールして現れるたびに 遅延読み込み(Lazy-Load)する方法を説明します‼️
「ネイティブLazy-Load」のみでは対応できず 同期/非同期処理の実装とかも面倒なので、最新Lazy-Load用JSライブラリ「Defer.js」の力を借ります。
埋め込みコード貼り付けのままで スクロールで遅延読み込み 対象にするため、「CSSクラス名の変更」と「親要素(div)の追加」をJS(JavaScript)で行います❗️
最後に一度だけ実行すれば良い、<script> 〜 </script> 部分の削除 は必要ですが…
重い「JS / CSS」などを preload(事前読み込み)する方法も説明します。
初心者向けの「記事」を、追加しました❗️
PSI パフォーマンス・スコアが80点未満の方は…
高速表示かつPSIスコア対策で、遅延読み込みは必須
あなたのサイトの「ページ高速表示」かつ「Google PageSpeed Insights(PSI)スコア対策」の理由で、ネイティブLazy-Load などを利用した 遅延読み込み(遅延ロード / Lazy-Load)は 必須でしょう。
一般的に、SNS埋め込みコードから「<script> 〜 </script> 部分(指定JS)を削除」後、</body> 直前で(DOMツリー構築後に)指定JSを一度だけ実行すれば 遅延読み込み可能です。
最後に指定JSを一度だけ実行すれば ページ内に含まれる SNSの全要素が レンダリング(データ読み込み+要素の追加・変更+要素の表示)されるため、「一括レンダリング」と呼ぶことにします。
Lazy-Load を実現する 手っ取り早い手段は、このような「DOMツリー構築完了+指定時間」後のレンダリング。
もう一つの手段は、スクロールで ビューポート(画面に現在表示されている領域)に 該当要素が現れるたびに その要素のレンダリングを行います。
PCやスマホで操作しなければ データのダウンロード自体を行わないため スマホのパケ代にも貢献しますが、前述の手段(一括レンダリング)と比べると 実装コード量が増えるなど 難易度は高くなります。
ブラウザ機能の ネイティブLazy-Load は後述の賢い手段で実現されていますが、残念ながら「静的な img iframe 要素」(画像や、YouTube動画 / Googleマップ などの埋め込み)にしか対応しておらず、(SNS埋め込みなどで) iframe 要素が動的に生成されるパターンでは ネイティブLazy-Load を利用できません。
どちらの手段を選んでも PSIスコア には貢献するはずですが、とくに Twitterタイムライン埋め込みをスクロールで遅延読み込みするのは(表示が遅れがちな場合があるほど)負荷が大きい ため ブログやホームページの管理者は 二択する必要があります。
指定時間後に、一括で 遅延読み込みするコード
各SNS埋め込み数が少なければ(3個以下程度)、以下の対応方法がオススメです。
Defer.js ライブラリを利用して 手軽な 前述の手段(一括レンダリング)で実装した場合のコードは、以下。
ツイート埋め込みコード blockquote 要素、タイムライン埋め込みコード a 要素 後の
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
の部分は、すべて削除してください‼️
Instagram 埋め込み埋め込みコード blockquote 要素 後の
<script async src="//www.instagram.com/embed.js"></script>
の部分は、すべて削除してください‼️
「HTMLのパース(解析)」と「DOMツリーの構築」後、
700ミリ秒 = 0.7秒後に 全ツイートとタイムラインを レンダリング。
1000ミリ秒 = 1秒後に 全Instagram埋め込みを レンダリング。
「Twitterツイート or Twitterタイムライン」を埋め込んだ時のみ、Twitter指定JSを実行。
Instagramを埋め込まなければ、Instagram指定JSを実行しません。
最後のパラメータを true にすると、(マウス操作など)ユーザーがアクションを起こすまで、指定JSの読み込みが保留されます。
( 指定した遅延時間後 すぐに 指定JSの読み込みを開始するのであれば、最後のパラメータを false に変更してください )
const tw_EmbedTW = document.getElementsByClassName('twitter-tweet'); // TWeet
const tw_EmbedTL = document.getElementsByClassName('twitter-timeline'); // TimeLine
if (tw_EmbedTW.length !== 0 || tw_EmbedTL.length !== 0) {
Defer.js('https://platform.twitter.com/widgets.js', 'twitter-js', 700, null, true);
}
const instaEmbed = document.getElementsByClassName('instagram-media'); // Instagram
if (instaEmbed.length !== 0) {
Defer.js('https://www.instagram.com/embed.js', 'insta-js', 1000, null, true);
}
( 上記JSコードは、 </body> 直前に挿入します )
01行め:Twitterツイートの埋め込みコード内に含まれるCSSクラス「twitter-tweet」にて、要素を抽出
02行め:Twitterタイムラインの埋め込みコード内に含まれるCSSクラス「twitter-timeline」にて、要素を抽出
03行め:ページ内の「ツイート+タイムライン」埋め込み数がZEROの場合、04行めは実行されません
04行め:ページ内の「ツイート+タイムライン」埋め込み数に関わらず(合計要素数が1以上の場合)、「指定JS(削除した部分のURL)」を </body> 直前で一度実行すればOKです‼️
Twitter 埋め込みコード
Twitter ツイート 手順
① オリジナルの埋め込みコード
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ブログを更新しました!<br>Lazy-Loadとは? PSIスコア改善方法2023 - ガジェおた(本館) <a href="https://t.co/EOwqpvwImk">https://t.co/EOwqpvwImk</a></p>— アタル⭐️😼Excel VBA for Mac をAppleScriptで補完中...😽⭐️ (@Ataruchi) <a href="https://twitter.com/Ataruchi/status/1646824691833733122?ref_src=twsrc%5Etfw">April 14, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
② script要素(指定JS)の削除
以下のように、末尾の <script> 〜 </script> 部分 を削除。
(ページ内に「Twitter ツイート」を複数埋め込んだ場合は、「この削除」を繰り返します)
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ブログを更新しました!<br>Lazy-Loadとは? PSIスコア改善方法2023 - ガジェおた(本館) <a href="https://t.co/EOwqpvwImk">https://t.co/EOwqpvwImk</a></p>— アタル⭐️😼Excel VBA for Mac をAppleScriptで補完中...😽⭐️ (@Ataruchi) <a href="https://twitter.com/Ataruchi/status/1646824691833733122?ref_src=twsrc%5Etfw">April 14, 2023</a></blockquote>
③ スクロールでレンダリングするには
「 Defer.js 」JSライブラリを利用して、スクロールで レンダリングするには…
以下のように、コードを書き換え❗️
埋め込み数が多いほど大変なため、実際には ③ を JSで行います‼️
- CSSクラス名を、任意のクラス名に変更
- 埋め込みコード全体を、親要素(div)で囲みます
【理由】
指定JS実行時に一括レンダリングされるのを防ぐため、埋め込みコード内のCSSクラスを一時的に変更。
「 iframe 要素が動的生成」される際、現要素の blockquote 要素は削除されてしまいます。
指定JS内の関数 twttr.widgets.load() の引数として 代わりに親要素を指定するため、div 親要素を追加。
class="twitter-tweet" → class="lazy-tweet"
(注)任意のCSSクラス名で良いが、今までに利用していないクラス名
親要素に対して Twitter の関数を呼び出す仕組みのため、親要素(div)を追加
(注)任意のCSSクラス名か「それぞれユニークなid」を持つ 親要素(div)にて、囲みます
親要素を「Twitter ツイート」埋め込みコード すべて に追加しないと、親要素が「投稿記事全体」など広範囲になる場合があり、スクロールでレンダリングできません
<div class="embed-twitter">
<blockquote class="lazy-tweet"><p lang="ja" dir="ltr">ブログを更新しました!<br>Lazy-Loadとは? PSIスコア改善方法2023 - ガジェおた(本館) <a href="https://t.co/EOwqpvwImk">https://t.co/EOwqpvwImk</a></p>— アタル⭐️😼Excel VBA for Mac をAppleScriptで補完中...😽⭐️ (@Ataruchi) <a href="https://twitter.com/Ataruchi/status/1646824691833733122?ref_src=twsrc%5Etfw">April 14, 2023</a></blockquote>
</div>
ブログを更新しました!
— アタル⭐️😼Excel VBA for Mac をAppleScriptで補完中...😽⭐️ (@Ataruchi) April 14, 2023
Lazy-Loadとは? PSIスコア改善方法2023 - ガジェおた(本館) https://t.co/EOwqpvwImk
Twitter タイムライン 手順
① オリジナルの埋め込みコード
<a class="twitter-timeline" data-tweet-limit="3" data-height="700" href="https://twitter.com/Ataruchi?ref_src=twsrc%5Etfw">Tweets by Ataruchi</a> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
オリジナルの「タイムライン」埋め込みコードに追加した属性
- data-tweet-limit=”ツイート数"
- data-height="700" (ピクセル単位)
※ Twitter「タイムライン」に追加できる属性の詳細は、以下の記事を参照
② script要素(指定JS)の削除
以下のように、末尾の <script> 〜 </script> 部分 を削除。
(ページ内に「Twitter タイムライン」を複数埋め込んだ場合は、「この削除」を繰り返します)
<a class="twitter-timeline" data-tweet-limit="3" data-height="700" href="https://twitter.com/Ataruchi?ref_src=twsrc%5Etfw">Tweets by Ataruchi</a>
③ スクロールでレンダリングするには
「 Defer.js 」JSライブラリを利用して、スクロールで レンダリングするには…
以下のように、コードを書き換え❗️
埋め込み数が多いほど大変なため、実際には ③ を JSで行います‼️
- CSSクラス名を、任意のクラス名に変更
- 埋め込みコード全体を、親要素(div)で囲みます
【理由】
指定JS実行時に一括レンダリングされるのを防ぐため、埋め込みコード内のCSSクラスを一時的に変更。
「 iframe 要素が動的生成」される際、現要素の a 要素は削除されてしまいます。
指定JS内の関数 twttr.widgets.load() の引数として 代わりに親要素を指定するため、div 親要素を追加。
class="twitter-timeline" → class="lazy-timeline"
(注)任意のCSSクラス名で良いが、今までに利用していないクラス名
親要素に対して Twitter の関数を呼び出す仕組みのため、親要素(div)を追加
(注)任意のCSSクラス名か「それぞれユニークなid」を持つ 親要素(div)にて、囲みます
親要素を「Twitter タイムライン」埋め込みコード すべて に追加しないと、親要素が「投稿記事全体」など広範囲になる場合があり、スクロールでレンダリングできません
<div class="embed-twitter">
<a class="lazy-timeline" data-tweet-limit="3" data-height="700" href="https://twitter.com/Ataruchi?ref_src=twsrc%5Etfw">Tweets by Ataruchi</a>
</div>
Tweets by Ataruchi
Instagram 埋め込みコード
Instagram 手順
① オリジナルの埋め込みコード
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/Cai4PiOpD35/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="14" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);">
<!-- 省略 -->
</blockquote> <script async src="//www.instagram.com/embed.js"></script>
② script要素(指定JS)の削除
以下のように、末尾の <script> 〜 </script> 部分 を削除。
(ページ内に「Instagram」を複数埋め込んだ場合は、「この削除」を繰り返します)
<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/Cai4PiOpD35/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="14" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);">
<!-- 省略 -->
</blockquote>
③ スクロールでレンダリングするには
「 Defer.js 」JSライブラリを利用して、スクロールで レンダリングするには…
以下のように、コードを書き換え❗️
埋め込み数が多いほど大変なため、実際には ③ を JSで行います‼️
- CSSクラス名を、任意のクラス名に変更
- 埋め込みコード全体を、親要素(div)で囲みます
【理由】
指定JS実行時に一括レンダリングされるのを防ぐため、埋め込みコード内のCSSクラスを一時的に変更。
「 iframe 要素が動的生成」される際、現要素の blockquote 要素は削除されてしまいます。
指定JS内の関数 instgrm.Embeds.process() の引数として 代わりに親要素を指定するため、div 親要素を追加。
class="instagram-media" → class="lazy-instagram"
(注)任意のCSSクラス名で良いが、今までに利用していないクラス名
親要素に対して Instagram の関数を呼び出す仕組みのため、親要素(div)を追加
(注)任意のCSSクラス名か「それぞれユニークなid」を持つ 親要素(div)にて、囲みます
親要素を「Instagram」埋め込みコード すべて に追加しないと、親要素が「投稿記事全体」など広範囲になる場合があり、スクロールでレンダリングできません
<div class="embed-insta">
<blockquote class="lazy-instagram" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/Cai4PiOpD35/?utm_source=ig_embed&utm_campaign=loading" data-instgrm-version="14" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);">
<!-- 省略 -->
</blockquote>
</div>
/body 直前に組み込むコード
( 2023/05/24 Chromeブラウザにて不具合が発生する場合があるため、rootMargin: "150% 0" 指定を rootMargin: "150% 0%" に修正しました )
Defer.js ライブラリ(v3.4.0以降)をセットアップ後に「スクロールで遅延読み込み」の効果を簡単にテストできるよう、 </body> 直前に組み込むコードをまとめた jsファイル(try catch付き、2.27Kbyte)を提供しています。
( Minify1.54Kbyte:scroll_lazyload_min.js )
Defer.js() 関数の 3つめのパラメータ(遅延ミリ秒)に 0 (ZERO) を指定しているため、「HTMLのパース(解析)+DOMツリー構築」後 すぐに 指定URLのJSが読み込まれ実行されます。
(注)すべての Twitter / Instagram 埋め込みコードから、 <script> 〜 </script> の部分は削除しておいてください。
【 JetTheme テンプレート(テーマ)以外 】
</body> 直前に、以下の htmlコード を追加。
※ Minifyコードを利用する場合、URL内のファイル名を scroll_lazyload_min.js に変更してください
<script>
Defer.js('https://past.gadgets-geek.net/js/scroll_lazyload.js', 'scroll-js', 0);
</script>
【 JetTheme テンプレート(テーマ) 】
jtCallback() 関数内に、以下の jsコード を追加。
※ Minifyコードを利用する場合、URL内のファイル名を scroll_lazyload2_min.js に変更してください
( scroll_lazyload2.js と scroll_lazyload.js の違いは、Defer.dom2関数 利用のみ )
Defer.js('https://past.gadgets-geek.net/js/scroll_lazyload2.js', 'scroll-js', 0);
手順③を、JavaScriptで実行
Defer.js ライブラリ 機能の詳細は、筆者が翻訳したドキュメントを参照してください。
手順 ③ は 既存の記事すべてに適用する場合 埋め込み数が多いほど大変なため、 </body> タグ直前で JS (JavaScript)で行います。
DOMツリー構築後に 行う必要があるため、Defer.js ライブラリの力を借りると簡単です。
以下コードは 手順③のとおりに、次のような ユニークな id 付きの div 要素で囲んだ後、CSSクラス名を変更。
- tw-tw-連番:Twitter ツイート
- tw-tl-連番:Twitter タイムライン
- insta-連番:Instagram
02行め: = document.getElementsByClassName('twitter-tweet');
を利用すると 動的なHTMLコレクション が返されるため、'twitter-tweet' CSSクラス名付きの全要素を 'lazy-tweet' に置換できない事例(一部の該当要素が置換されないバグ)を含んでしまいます。
筆者もデバッグ作業で気付き、getElementsByClassName('twitter-tweet') から querySelectorAll('.twitter-tweet') に書き換えました。😖
<script type="deferjs">
const tw_EmbedTW = document.querySelectorAll('.twitter-tweet');
const tw_EmbedTL = document.querySelectorAll('.twitter-timeline');
const instaEmbed = document.querySelectorAll('.instagram-media');
let num = 0; // Twitter TWeet
tw_EmbedTW.forEach(function(node) {
let p_node = document.createElement('div');
p_node.id = ('tw-tw-' + ++num);
node.parentNode.insertBefore(p_node, node);
p_node.appendChild(node);
node.classList.replace('twitter-tweet', 'lazy-tweet');
});
num = 0; // Twitter TimeLine
tw_EmbedTL.forEach(function(node) {
let p_node = document.createElement('div');
p_node.id = ('tw-tl-' + ++num);
node.parentNode.insertBefore(p_node, node);
p_node.appendChild(node);
node.classList.replace('twitter-timeline', 'lazy-timeline');
});
num = 0; // Instagram
instaEmbed.forEach(function(node) {
let p_node = document.createElement('div');
p_node.id = ('insta-' + ++num);
node.parentNode.insertBefore(p_node, node);
p_node.appendChild(node);
node.classList.replace('instagram-media', 'lazy-instagram');
});
</script>
Defer.js ライブラリでは、type="deferjs" 属性指定した script要素を、「HTMLのパース解析・DOMツリー構築」後に 同期実行します❗️
暗黙のうちに、Defer.all() 関数が 初期値で実行されています。
「初期状態で Defer.js ライブラリが組み込まれている JetTheme テンプレート(テーマ)」では、上記コードの代わりに jtCallback() 関数内に 以下を追加します。
const tw_EmbedTW = document.querySelectorAll('.twitter-tweet');
const tw_EmbedTL = document.querySelectorAll('.twitter-timeline');
const instaEmbed = document.querySelectorAll('.instagram-media');
let num = 0; // Twitter TWeet
tw_EmbedTW.forEach(function(node) {
let p_node = document.createElement('div');
p_node.id = ('tw-tw-' + ++num);
node.parentNode.insertBefore(p_node, node);
p_node.appendChild(node);
node.classList.replace('twitter-tweet', 'lazy-tweet');
});
num = 0; // Twitter TimeLine
tw_EmbedTL.forEach(function(node) {
let p_node = document.createElement('div');
p_node.id = ('tw-tl-' + ++num);
node.parentNode.insertBefore(p_node, node);
p_node.appendChild(node);
node.classList.replace('twitter-timeline', 'lazy-timeline');
});
num = 0; // Instagram
instaEmbed.forEach(function(node) {
let p_node = document.createElement('div');
p_node.id = ('insta-' + ++num);
node.parentNode.insertBefore(p_node, node);
p_node.appendChild(node);
node.classList.replace('instagram-media', 'lazy-instagram');
});
ユニークな id ではなく、任意の CSSクラス名 付きの div 要素で囲んだ後、CSSクラス名を変更するコードは以下。
(JSコード部分のみ)
const tw_EmbedTW = document.querySelectorAll('.twitter-tweet');
const tw_EmbedTL = document.querySelectorAll('.twitter-timeline');
const instaEmbed = document.querySelectorAll('.instagram-media');
// Twitter TWeet
tw_EmbedTW.forEach(function(node) {
let p_node = document.createElement('div');
p_node.className = 'embed-twitter';
node.parentNode.insertBefore(p_node, node);
p_node.appendChild(node);
node.classList.replace('twitter-tweet', 'lazy-tweet');
});
// Twitter TimeLine
tw_EmbedTL.forEach(function(node) {
let p_node = document.createElement('div');
p_node.className = 'embed-twitter';
node.parentNode.insertBefore(p_node, node);
p_node.appendChild(node);
node.classList.replace('twitter-timeline', 'lazy-timeline');
});
// Instagram
instaEmbed.forEach(function(node) {
let p_node = document.createElement('div');
p_node.className = 'embed-insta';
node.parentNode.insertBefore(p_node, node);
p_node.appendChild(node);
node.classList.replace('instagram-media', 'lazy-instagram');
});
Twitter 指定JSの実行
JetTheme 以外の場合は 先程の script 内の最後に、以下を追加。
JetTheme の場合は 先程のコードの後に、以下を追加。( Defer.dom → Defer.dom2 の変更も必要 )
(注)Twitter ツイート と タイムラインが 両方含まれない場合は、指定JSを実行しません
非同期で実行される Defer.js() 関数で 指定JSを読み込んで実行完了後に Defer.dom() 関数を呼び出すため、組み合わせて利用。
nodeごとに twttr.widgets.load() 関数が実行されますが、この対象要素として 通常の node ではなく 親要素 が指定されていることに注意してください。
同関数の実行が終了するまでに node(lazy-tweet または lazy-timeline CSSクラス名に書き換えた要素)は削除されてしまうため、あらかじめ node を div 要素で囲み 親要素を追加しておきます。
const tw_EmbedTW2 = document.getElementsByClassName('lazy-tweet');
const tw_EmbedTL2 = document.getElementsByClassName('lazy-timeline');
if (tw_EmbedTW2.length !== 0 || tw_EmbedTL2.length !== 0) {
Defer.js('https://platform.twitter.com/widgets.js', 'twitter-js', 700, function() {
Defer.dom('.lazy-tweet, .lazy-timeline', 0, null, function(node) {
if (node.className === 'lazy-timeline') {
node.className = 'twitter-timeline';
} else {
node.className = 'twitter-tweet';
}
twttr.widgets.load(node.parentNode);
}, {rootMargin: "150% 0%"});
});
}
08,10行め:オリジナルの CSSクラス名に戻します。
node.className = 'twitter-tweet tw-align-center';
のように 戻す際は 複数の CSSクラス名を指定可能。
(tw-align-center:ツイート表示をセンタリング)
13行め:rootMargin で、どのくらい前後からレンダリングを始めるか 調整可能。
CSSの margin のように指定可能で、 "100% 0%" だと ビューポート(1画面)分 前後からレンダリングが開始されます。
古いスマホでもタイミングよく表示させるには、 "200% 0%" 程度を指定。
( 2023/05/24 rootMargin には 絶対指定の場合 px 相対指定の場合 % を利用しますが、Chromeブラウザにて 0px または 0% と指定しないと不具合が発生する場合があるため、修正しました )
※ Twitterの ツイート と タイムライン、別々のタイミングでレンダリングを開始させたい場合
const tw_EmbedTW2 = document.getElementsByClassName('lazy-tweet');
const tw_EmbedTL2 = document.getElementsByClassName('lazy-timeline');
if (tw_EmbedTW2.length !== 0 || tw_EmbedTL2.length !== 0) {
Defer.js('https://platform.twitter.com/widgets.js', 'twitter-js', 700, function() {
Defer.dom('.lazy-timeline', 0, null, function(node) {
node.className = 'twitter-timeline';
twttr.widgets.load(node.parentNode);
}, {rootMargin: "200% 0%"});
Defer.dom('.lazy-tweet', 0, null, function(node) {
node.className = 'twitter-tweet';
twttr.widgets.load(node.parentNode);
}, {rootMargin: "150% 0%"});
});
}
Instagram 指定JSの実行
JetTheme 以外の場合は 先程の script 内の最後に以下を追加。
JetTheme の場合は 先程のコードの後に以下を追加。( Defer.dom → Defer.dom2 の変更も必要 )
(注)Instagram 埋め込みが 含まれない場合は、指定JSを実行しません
非同期で実行される Defer.js() 関数で 指定JSを読み込んで実行完了後に Defer.dom() 関数を呼び出すため、組み合わせて利用。
nodeごとに instgrm.Embeds.process() 関数が実行されますが、この対象要素として 通常の node ではなく 親要素 が指定されていることに注意してください。
同関数の実行が終了するまでに node(lazy-instagram CSSクラス名に書き換えた要素)は削除されてしまうため、あらかじめ node を div 要素で囲み 親要素を追加しておきます。
const instaEmbed2 = document.getElementsByClassName('lazy-instagram');
if (instaEmbed2.length !== 0) {
Defer.js('https://www.instagram.com/embed.js', 'insta-js', 1000, function() {
Defer.dom('.lazy-instagram', 0, null, function(node) {
node.className = 'instagram-media';
instgrm.Embeds.process(node.parentNode);
}, {rootMargin: "150% 0%"});
});
}
06行め:オリジナルの CSSクラス名に戻します。
08行め:rootMargin で、どのくらい前後からレンダリングを始めるか 調整可能。
CSSの margin のように指定可能で、 "100% 0%" だと ビューポート(1画面)分 前後からレンダリングが開始されます。
古いスマホでもタイミングよく表示させるには、 "200% 0%" 程度を指定。
( 2023/05/24 rootMargin には 絶対指定の場合 px 相対指定の場合 % を利用しますが、Chromeブラウザにて 0px または 0% と指定しないと不具合が発生する場合があるため、修正しました )
重いJS・CSSファイルなどを、preload
preload とは「リソース(プリロード)ヒント」とも呼ばれる機能で、「HTML解析中に、バックグラウンドでファイルをダウンロード希望」とブラウザに対してヒントを与えます。
(ブラウザ判断ですが)バックグラウンドで指定ファイルがダウンロードされた場合、利用時のダウンロード時間が短縮されるため PSI パフォーマンス・スコアが良くなることが多いようです。
筆者の環境では、Prism.js用のCSS+JSファイルを preload しただけで、5ポイント以上アップしました。
なお、Defer.js ライブラリの Defer.all() 関数で指定したJSスクリプトには、preload が自動適用されます。
ほとんど何でも preload 可能ですが、以下の例では ファイルサイズが大きめの Prism.js 用のCSSファイルとJSファイルを preload しています。
jsファイルの場合 as='script' 、 cssファイルの場合 as='style' と指定。
※ head 要素内に記述します❗️
<head>
<!-- 省略 -->
<link as='style' href='https://past.gadgets-geek.net/css/prism.css' rel='preload'/>
<link as='script' href='https://past.gadgets-geek.net/js/prism129.js' rel='preload'/>
<!-- 省略 -->
</head>
以下は、Twitter と Instagram のJSを preload する例です。
<head>
<!-- 省略 -->
<link as='script' href='https://platform.twitter.com/widgets.js' rel='preload'/>
<link as='script' href='https://www.instagram.com/embed.js' rel='preload'/>
<!-- 省略 -->
</head>
(注)投稿記事のみ preload する場合など、「条件分岐」の利用を推奨します。
以下は、WordPress 利用時の「条件分岐まとめ」記事。
Defer.jsのセットアップ
「 Defer.js 」JSライブラリ は、ほとんど何でも 遅延読み込み できます‼️
- わずか 1.81KByte で、インライン組み込み推奨
- JS や CSS だけでなく、関数単位でも 遅延読み込み 可能
- ネイティブLazyLoad 対象要素も、遅延読み込みタイミングを変更可能
- Prism.js / highlight.js も、スクロールで 遅延読み込み
- Google AdSense / Analytics も、遅延読み込み
Defer.js の「セットアップ」や「詳細の利用方法」は、筆者がまとめた以下記事を参照ください❗️
( 長編記事のため、「目次」利用が便利です )
最後まで読んでいただき、ありがとうございます。 また、お越しくださいませ。
// アタル