Twitter Instagram 埋め込みをスクロールで遅延読み込み

Twitter / Instagram LazyLoad by scroll

 複数の「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>&mdash; アタル⭐️😼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>&mdash; アタル⭐️😼Excel VBA for Mac をAppleScriptで補完中...😽⭐️ (@Ataruchi) <a href="https://twitter.com/Ataruchi/status/1646824691833733122?ref_src=twsrc%5Etfw">April 14, 2023</a></blockquote>

③ スクロールでレンダリングするには

Twitter-tweet-Chart: LazyLoad by scroll

 「 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>&mdash; アタル⭐️😼Excel VBA for Mac をAppleScriptで補完中...😽⭐️ (@Ataruchi) <a href="https://twitter.com/Ataruchi/status/1646824691833733122?ref_src=twsrc%5Etfw">April 14, 2023</a></blockquote>
</div>


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>

③ スクロールでレンダリングするには

Twitter-timeline-Chart: LazyLoad by scroll

 「 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>




Instagram 埋め込みコード

Instagram 手順


① オリジナルの埋め込みコード

<blockquote class="instagram-media" data-instgrm-captioned data-instgrm-permalink="https://www.instagram.com/p/Cai4PiOpD35/?utm_source=ig_embed&amp;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&amp;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>

③ スクロールでレンダリングするには

Instagram-Chart: LazyLoad by scroll

 「 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&amp;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.jsscroll_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.domDefer.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.domDefer.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>

 以下は、TwitterInstagram の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 で、インライン組み込み推奨
  • JSCSS だけでなく、関数単位でも 遅延読み込み 可能
  • ネイティブLazyLoad 対象要素も、遅延読み込みタイミングを変更可能
  • Prism.js / highlight.js も、スクロールで 遅延読み込み
  • Google AdSense / Analytics も、遅延読み込み


 Defer.js の「セットアップ」や「詳細の利用方法」は、筆者がまとめた以下記事を参照ください❗️
( 長編記事のため、「目次」利用が便利です )





Macブログ ランキング アイコン
最後まで読んでいただき、ありがとうございます。 また、お越しくださいませ。
// アタル
For follow LINE Reader Group!Subscribe to this blog on Feedly!

Previous Post
No Comment
Add Comment
comment url