Bloggerの投稿画像の自動的な遅延読み込みを確実に行うためのプログラム 結城永人 - 2022年3月5日 (土) Bloggerの投稿画像をHTMLのloading-lazyで自動化するプログラムを紹介したけれども動作を詳しく調べた結果、AndroidのChromeで初回画面から2000pxくらい下の画面外の画像しか遅延読み込みが発動しなかった。さらにYouTube動画を止めることは全くできなかった。ブラウザの対応状況はどれも同じではないと聞くけれどもたぶん大きな違いはないかも知れない。 何れにしてもHTMLのloading-lazyによるブログの表示速度の高速化は非常に限定的だと分かったので、もはや元々のJavaScriptのIntersection Observer APIを再び使って画面外の画像や動画を確実に止めてパフォーマンスをきっちり上げるためのプログラムへの書き換えを追加したくなった。 合格した監査|PageSpeed Insights|Google Developers PageSpeed Insightsでチェックしても「オフスクリーン画像の遅延読み込み」に合格するからGoogle検索などの検索エンジンも把握してサイト評価を高めてブログのアクセスアップに繋がるかも知れない。 ブログへの取り付け方はloading-lazyのものと同じなので、本稿ではJavaScriptの本体のプログラムだけを掲載する。 使う人は制作者の結城永人の著作権の表記もソースコードに併せて載せておく(MITライセンスでカスタマイズも再配布も許可する)から消さないで欲しい。 僕が提供している非公式テーマのImaginaryを使っている場合は著作権の表記が含まれているから今回の分を繰り返す必要はない。 目次Intersection Observerのバージョン画像だけを遅延読み込みするソースコード画像の横並びが上手く行かない場合の対策YouTube動画も遅延読み込みする場合記事のJavaScriptの実行用プログラム画像にdecoding-asyncを付ける場合軽量化のWebPなどと併用するソースコード記事のJavaScriptの実行用プログラム遅延読み込みの動作確認用のプログラム Intersection Observerのバージョン 画像だけを遅延読み込みするソースコード 初回画像に入らない画像の読み込みを止める。 サンプルでは判定を、240px、増やしたから厳密には初回画像から、2401px、下の見えない画像は即座に読み込まれる。画面に入った瞬間から画像が読み込まれるとそこから時間がかかって長く待たされる可能性がある。だから画面に入る瞬間よりも少し早めに読み込みを開始する方がスムーズに表示できるので、判定の余白を取る。 JavaScript /* Copyright: Nagahito Yuki 2022 | https://www.nagahitoyuki.com/2022/03/a-program-to-ensure-automatic-lazy-loading-of-posted-images-on-blogger.html | License: The MIT License */ const psbd = Blog1.querySelector("div.post-body"), blct = psbd.querySelector("noscript.blog-content"), npsbd = psbd.cloneNode(false), nl = document.createElement("div"); nl.style.height = "100vh"; psbd.insertBefore(nl, blct); npsbd.insertAdjacentHTML("afterbegin", blct.innerText); const blimgs = npsbd.querySelectorAll("img"); if (blimgs[0]) { Promise.all([...blimgs].map(blimg => { const aroi = blimg.dataset.originalWidth / blimg.dataset.originalHeight; if (blimg.height) { if (!blimg.width && aroi) blimg.width = blimg.height * aroi; } else if (blimg.width) { if (aroi) blimg.height = blimg.width / aroi; } else if (aroi && !blimg.style.aspectRatio) { blimg.style.aspectRatio = aroi; } if (!blimg.alt) blimg.alt = "<data:messages.image/>"; blimg.dataset.src = blimg.src; blimg.src = ""; return blimg; })).then(results => { psbd.parentNode.replaceChild(npsbd, psbd); const postContentObserver = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { const et = entry.target; et.src = et.dataset.src; delete et.dataset.src; postContentObserver.unobserve(et); }}); }, { rootMargin: "240px" }); results.forEach(result => { if ("IntersectionObserver" in window) postContentObserver.observe(result); else result.src = result.dataset.src; }); }); } else { psbd.parentNode.replaceChild(npsbd, psbd); } ※冒頭のコメント(/* ... */)はソースコードの著作権の表記。 初回画面の下から240px以内に入った画像だけが読み込まれる。 プログラムの「rootMargin: "240px" 」の数値が判定の余白になっているので、好みで調節することができる。縮めると画像が画面に入る近くで、読み込まれる。0ならば画面に入る瞬間から読み込まれる。伸ばすと画面に入る遠くから読み込まれることになる。早めに読み込みを開始すると大きなサイズなどの読み込みにかかる画像の待ち時間を減らせる。 画像の遅延読み込みには関係ないけれども画像に縦幅と横幅の片方があればもう一方を付けるようにしてある。ブラウザが画像の縦横比を知るとスムーズに表示できて高速化に役立つといわれるから行う。 縦幅と横幅に関してはloading-lazyのものと同じなので、「元のサイズ」で取り込んだ画像に新しく付ける方法などは割愛する。 画像の横並びが上手く行かない場合の対策 通常の使用では問題がないけれども画像の横並びを行ったときにスムーズに表示されなくなる不具合が確認された。 Search Consoleのモバイルユーザビリティで、エラーになることも確認されているので、少なくともGoogle検索からアクセスアップを望む場合には必ず対処した方が良いと思う。 対策①一部の投稿画像の遅延読み込みを除外する 投稿画像に遅延読み込みを使わなければ横並びのデザインに支障を来すことはない。 投稿画像の親要素、横並びを行う際にはdivタグなどを使うので、そこにclass属性を何か付けておく。 HTML <div class="normal">投稿画像</div> そして基本のソースコードの画像を取得する「const blimgs = npsbd.querySelectorAll("img");」の「img」をHTMLで付けたclass属性があるものに変える。 JavaScript const blimgs = npsbd.querySelectorAll("div:not(.normal) img"); 帯文字の「div」と「normal」が遅延読み込みを除外する投稿画像の親要素のHTMLタグの種類とclass属性の値になる。 この場合、遅延読み込みをかけたい投稿画像の親要素にも除外するものと同じ種類のタグで、class属性がないかあれば別の値を付けておかなくてはならない。 Bloggerでは投稿画像の親要素にdivタグが必ず付くので、横並びの場合の親要素にもdivタグを使えば問題はない。変える場合は遅延読み込みをかけるものとかけないもので、親要素に使うHTMLタグの種類を合わせておく必要がある。 対策②横並びを指定する列指定の単位を変える これは上手く行かない場合もあって特に投稿画像の軽量化のレスポンシブ配信を追加すると芳しくないので、どうしても無理ならば対策①を使わなくてはならない。 列指定のgrid-template-columnsで分割する単位に「fr」を使うと二段(縦二列)以上の場合に大きなサイズの画像が先に読み込まれたときに収まり切らずにはみ出す恐れがある。別の「%」では避けられたから投稿のグリッドレイアウトでは使わなくてはならない。 追記:2023年2月からデザインが崩れない二枚の縦一列の横並びでもSearch Consoleのモバイルユーザビリティのエラーになるように変わった。だから全ての画像の横並びで対処しないとGoogle検索などの検索エンジンからの訪問者を減らすかも知れない。 同時に隙間のgapを使うと幅に加算されてずれ易くなるので、そのときは計算式のcalc()でgapの値をセルの数で割ってそれぞれの「%」から引くと整えられる。 例えばgrid-template-columnsが「50% 50%」で、gapが「1em」ならば「calc(50% - 0.5em) calc(50% - 0.5em)」にすると二つの同じ大きさのセルが「1em」の隙間で親ボックスにぴったり収まるようになる。 loading-lazyのプログラムでは画像のはみ出しを親要素から切り捨てることもできたけれどもIntersection Observeのプログラムではできない。 プログラムに使用しているJavaScriptのIntersection Observer APIのブラウザの対応状況(IntersectionObserver)は良好で、人気のブラウザの多くでは動作するけれども動作しない場合は何もせずに画面を含めて記事を本文を表示するようになっている。 関連ページBloggerの投稿画像の確実な遅延読み込みの自動化のJavaScriptプログラムの説明付きソースコード YouTube動画も遅延読み込みする場合 基本のソースコードの二ヵ所を変更する。 変更① const blimgs = npsbd.querySelectorAll("img, iframe"); ※太字が追加部分。 変更② if (blimgs[0]) { Promise.all([...blimgs].map(blimg => { (中略) if ("IntersectionObserver" in window) postContentObserver.observe(result); else result.src = result.dataset.src; }); }); } else { psbd.parentNode.replaceChild(npsbd, psbd); } ※打ち消し線が削除部分。 遅延読み込みの対象がiframeタグなので、YouTubeだけではなくて同じ要素を使ったものは画面外で止められることになる。 YouTubeだけにしたい場合は固有のidやclassをYouTubeの埋め込みのソースコードに付けておいてプログラムの変更①の「iframe」と置き換えて指定すれば大丈夫だ。 画像にdecoding-asyncを付ける場合 初回画面の遅延読み込みしない画像にHTMLのdecoding-asyncを付けると優先的に読み込まれて普通よりも早く表示できる。 基本のソースコードの一ヵ所を変更する。 JavaScript if (entry.isIntersecting) { const et = entry.target; if (et.boundingClientRect.top < window.innerHeight) et.decoding = "async"; et.src = et.dataset.src; delete et.dataset.src; postContentObserver.unobserve(et); } ※太字が追加部分。 YouTube動画を追加した場合はdecoding-asyncを付けても優先的に読み込まれないから除外した方が良い。 JavaScript if (entry.isIntersecting) { const et = entry.target; if (et.tagName === "IMG" && et.boundingClientRect.top < window.innerHeight) et.decoding = "async"; et.src = et.dataset.src; delete et.dataset.src; postContentObserver.unobserve(et); } ※太字が追加部分。 画像のdecoding-asyncのソースコードに「et.tagName === "IMG" &&」を追加する。 軽量化のWebPなどと併用するソースコード ブログのパフォーマンスを上げるには画像URLのパラメーターを操作して軽量化のWebPのファイル形式に変えたり、ブラウザが保存して二回目以降に読み込まずに済ませられるキャッシュ期限を付けるとさらに効果的なので、遅延読み込みと併用する場合のソースコードを紹介する。 JavaScript const bisrc = blimg.src, aroi = blimg.dataset.originalWidth / blimg.dataset.originalHeight; if (/blogger\.googleusercontent\.com\/img\/a\//.test(bisrc)) { blimg.dataset.src = /=.*$/.test(bisrc) ? bisrc + "-rw" : bisrc + "=rw"; } else { if (/\.(jpg|jpeg)/i.test(bisrc)) { const pmoi = /^(.+\/)(.*)(\/.*)$/.exec(bisrc); blimg.dataset.src = pmoi[1] + pmoi[2] + "-rw" + pmoi[3]; } else { blimg.dataset.src = bisrc; }} if (blimg.height) { if (!blimg.width && aroi) blimg.width = blimg.height * aroi; } else if (blimg.width) { if (aroi) blimg.height = blimg.width / aroi; } else if (aroi && !blimg.style.aspectRatio) { blimg.style.aspectRatio = aroi; } if (!blimg.alt) blimg.alt = "<data:messages.image/>"; blimg.dataset.src = blimg.src; blimg.src = ""; return blimg; })).then(results => { ※太字が変更部分。 基本のソースコードに所定のソースコードを追加して不要な部分を削除する。 サンプルでは軽量化のWebPの「rw」と百日のキャッシュ期限の「e100」の画像パラメーターが付くようになっている。 画像パラメーターのカスタマイズについては遅延読み込みと同じように自動化を設定する個別ページで機能を含めて種々と説明している。 遅延読み込みのカスタマイズでYouTube動画を追加したり、decoding-asyncを付けたりする方法は通常の場合と変わらない。 記事のJavaScriptの実行用プログラム 記事の本文にscriptタグで記載したソースコードがある場合に止まってしまうので、実行できるようにするプログラムを追加する必要がある。 JavaScript const pbscs = npsbd.querySelectorAll("script"); if (pbscs[0]) { pbscs.forEach(pbsc => { const npbsc = document.createElement("script"); if (pbsc.src) npbsc.src = pbsc.src; if (pbsc.async) npbsc.async = "async"; if (pbsc.textContent) npbsc.textContent = pbsc.textContent; npsbd.replaceChild(npbsc, pbsc); }); } 遅延読み込みの基本のソースコードに続けて同じscriptタグの中に入れておく。 遅延読み込みの動作確認用のプログラム 遅延読み込みのプログラムは目に見えるものではないので、ブログにちゃんと組み込めたかどうかをチェックできるプログラムも紹介する。 JavaScript results.forEach(result => { result.onload = () => { alert((result.tagName === 'IMG' ? '画像' : '動画') + "の読み込みが完了しました\u3002\ndecoding属性は\u300c" + result.getAttribute("decoding") + "\u300dの状態です\u3002"); } if ("IntersectionObserver" in window) postContentObserver.observe(result); else result.src = result.dataset.src; }); ※太字が変更部分。 画像や動画の読み込みが完了した時点で、「読み込みが完了ひました」というポップアップが出る。 初回画面の画像や動画はブログの記事を開いて直ぐに読み込みが完了するし、もっと下の画面外のものはスクロールで近付いたところから(容量が大きい画像やYouTube動画は少し待たされて)読み込みが完了するので、合わなければプログラムがちゃんと組み込まれてないと分かる。 decoding属性の値も示すので、付いていれば「async」、付いてなければ「null」と表示される。decoding-asyncを使用する場合、初回画面の画像に付いていて画面外の画像や全ての動画に付いてないことを確認できる。 コメント Rainbow Goblins2023年1月22日 16:23このプログラムを使わしていただこうと思い、導入例に倣ってやってみたのですが、うまくいきません。もしよろしければ、どこが問題なのかご教授いただけないでしょうか?(投稿が通らないようなので、スクリプト部は特殊文字に変換しております。)テーマHTMLの書き換えはできているようです。他の動きも元のままです。うまくいかないと思った理由は、動作確認用のポップアップが出ないことと、PageSpeed Insights で「オフスクリーン画像を遅延読み込みする」が依然として残っていることです。Qooq オリジナル<div class='post-body entry-content' expr:id='"post-body-" + data:post.id' itemprop='articleBody'><data:post.body/><div style='clear: both;'/> <!-- clear for photos floats --></div>書き換え後<div class='post-body entry-content' expr:id='"post-body-" + data:post.id' itemprop='articleBody'><b:tag cond='data:blog.pageType == "item" or data:blog.pageType == "static_page and data:view.featuredImage' class='blog-content' name='noscript'><data:post.body/></b:tag><div style='clear: both;'/> <!-- clear for photos floats --></div><b:if cond='data:blog.pageType == "item" or data:blog.pageType == "static_page" and data:view.featuredImage'><script>遅延読み込み用ソースコード</script></b:if>返信削除返信結城永人2023年1月22日 18:52投稿が通らないというのはおかしいです。特殊文字に変換するところで、エラーが起きているかも知れません。今回のソースコードで止められるのは「&」と「>」で、それぞれに「&」と「>」に置き換えて掲載してますから大丈夫なんです。もう一つの方法として「&」と「>」を元の「&」と「>」に戻した上で、scriptタグの内側のソースコード全体をCDATAタグで囲むこともできます<script><![CDATA[遅延読み込み用ソースコード]]></script>このような仕方だと「&」と「>」をscript内のソースコードに使うことができますので、なるべく特殊文字に変換しないでやってみて下さい。補足としてtagタグとifタグのcond属性の「data:blog.pageType == "item" or data:blog.pageType == "static_page」の部分は半角括弧に入れて記載しないと画像なしのページを除外できません。cond='(data:blog.pageType == "item" or data:blog.pageType == "static_page) and data:view.featuredImage'もう一つ、Qooq オリジナルの「<div style='clear: both;'/> <!-- clear for photos floats -->」の部分が遅延読み込みのプログラムで消されますので、遅延読み込みのソースコードの冒頭部分の「const psbd……;」から「npsbd.insertAdjacentHTML……;」までを次のように修正して下さい。const psbd = Blog1.querySelector("div.post-body"), blct = psbd.querySelector("noscript.blog-content"), npsbd = psbd.cloneNode(false), nl = document.createElement("div"), dfi = document.createElement("div");nl.style.height = "100vh"; psbd.insertBefore(nl, blct); dfi.setAttribute("style", "clear:both;"); npsbd.appendChild(dfi); npsbd.insertAdjacentHTML("afterbegin", blct.innerText);Qooqなどの非公式テーマは他のソースコードの関係から遅延読み込みのソースコードが使えない場合もあるかも知れません。削除返信返信Rainbow Goblins2023年1月22日 23:02お教えいただいた3点をひとつずつ適用して、動作確認用のポップアップとPageSpeed Insights での「オフスクリーン画像を遅延読み込みする」をみましたが、やはり効いていないようです。さらに、素のQooQ(Version:2.00)を入手して、このプログラムを導入してみましたが、効いていないようです。削除返信返信結城永人2023年1月23日 5:45この記事では省略しましたが、レイアウトヴァージョン2のテンプレートは「 <data:post.body/>」を含む記事のためのソースコードがパソコン用とスマホ用の二つに分かれています(詳細)。前回のQooqのソースコードを見ると公式テーマのレイアウトヴァージョン2のスマホ用と同じです。なのでパソコン用に次のようなソースコードもあるかも知れません。<div class='post-body entry-content' expr:id='"post-body-" + data:post.id' expr:itemprop='(data:blog.metaDescription ? "" : "description ") + "articleBody"'> <data:post.body/> <div style='clear: both;'/> <!-- clear for photos floats --></div>通常はこちらの「<data:post.body/>」をカスタマイズしてテンプレートをスマホに対応させる場合はもう一つの「<data:post.body/>」もカスタマイズするようにします。公式テーマだとレイアウトヴァージョン2のパソコン用の「<data:post.body/>」はスマホ用のもっと先にありますので、Qooqも二つに分かれてないかどうかを確認してみて下さい。削除返信返信Rainbow Goblins2023年1月23日 10:17うまく動くようになりました。ポップアップとPageSpeedで確認しました。が2か所にあることには気づいていましたが、導入例に比べて下記に載せたように構文が簡素だったこととから、そちらは気に留めていませんでした。記事をもっとしっかりと読み込むべきでした。ご指摘いただいたように、もう一か所ののところを書き換えると、画像遅延が有効になりました。”遅延読み込み用ソースコード” の特殊文字を通常文字に戻す変更は適用していません。手厚いご教授をいただき、本当にありがとうございました。”遅延読み込み用ソースコード” は同じものを2か所に入れたのですが、これでよかったのでしょうか。[[QooQ オリジナル]]<div class='post-body' id='single-content'><data:post.body/><div style='clear: both;'/> <!-- clear for photos floats --></div>[[書き換え 2か所目]]<div class='post-body' id='single-content'><b:tag cond='data:view.featuredImage' class='blog-content' name='noscript'><data:post.body/></b:tag><div style='clear: both;'/> <!-- clear for photos floats --></div><b:if cond='data:view.featuredImage'><script>遅延読み込み用ソースコード</script></b:if>削除返信返信結城永人2023年1月23日 11:34正常に動作して良かったです。遅延読み込みのソースコードはパソコンとスマホで同じものを使うことができます。振り分けのcond属性はパソコン用とスマホ用が同じでも大丈夫ですけど、スマホ用の本文のソースコードは最初から記事/追加ページの専用ですから「data:view.featuredImage」だけでも画像なしのページを適切に除外できます。因みにレイアウトヴァージョン2のスマホ対応は公式テーマの場合は自動化されてません。Qooqも同じならばBloggerの管理画面のテーマのメニュー(カスタマイズの右横の▽)の「モバイルの設定」をモバイルの「カスタム」(パソコンと同じものをカスタマイズして使う場合)にしないとスマホで閲覧してもパソコン用のソースコードが適用されますので、注意して下さい。削除返信返信返信コメントを追加もっと読み込む... 新しい投稿 前の投稿
コメント
このプログラムを使わしていただこうと思い、導入例に倣ってやってみたのですが、うまくいきません。もしよろしければ、どこが問題なのかご教授いただけないでしょうか?(投稿が通らないようなので、スクリプト部は特殊文字に変換しております。)
返信削除テーマHTMLの書き換えはできているようです。他の動きも元のままです。
うまくいかないと思った理由は、動作確認用のポップアップが出ないことと、PageSpeed Insights で「オフスクリーン画像を遅延読み込みする」が依然として残っていることです。
Qooq オリジナル
<div class='post-body entry-content' expr:id='"post-body-" + data:post.id' itemprop='articleBody'>
<data:post.body/>
<div style='clear: both;'/> <!-- clear for photos floats -->
</div>
書き換え後
<div class='post-body entry-content' expr:id='"post-body-" + data:post.id' itemprop='articleBody'>
<b:tag cond='data:blog.pageType == "item" or data:blog.pageType == "static_page and data:view.featuredImage' class='blog-content' name='noscript'><data:post.body/></b:tag>
<div style='clear: both;'/> <!-- clear for photos floats -->
</div>
<b:if cond='data:blog.pageType == "item" or data:blog.pageType == "static_page" and data:view.featuredImage'>
<script>
遅延読み込み用ソースコード
</script>
</b:if>
投稿が通らないというのはおかしいです。特殊文字に変換するところで、エラーが起きているかも知れません。
削除今回のソースコードで止められるのは「&」と「>」で、それぞれに「&」と「>」に置き換えて掲載してますから大丈夫なんです。
もう一つの方法として「&」と「>」を元の「&」と「>」に戻した上で、scriptタグの内側のソースコード全体をCDATAタグで囲むこともできます
<script>
<![CDATA[
遅延読み込み用ソースコード
]]>
</script>
このような仕方だと「&」と「>」をscript内のソースコードに使うことができますので、なるべく特殊文字に変換しないでやってみて下さい。
補足としてtagタグとifタグのcond属性の「data:blog.pageType == "item" or data:blog.pageType == "static_page」の部分は半角括弧に入れて記載しないと画像なしのページを除外できません。
cond='(data:blog.pageType == "item" or data:blog.pageType == "static_page) and data:view.featuredImage'
もう一つ、Qooq オリジナルの「<div style='clear: both;'/> <!-- clear for photos floats -->」の部分が遅延読み込みのプログラムで消されますので、遅延読み込みのソースコードの冒頭部分の「const psbd……;」から「npsbd.insertAdjacentHTML……;」までを次のように修正して下さい。
const psbd = Blog1.querySelector("div.post-body"), blct = psbd.querySelector("noscript.blog-content"), npsbd = psbd.cloneNode(false), nl = document.createElement("div"), dfi = document.createElement("div");
nl.style.height = "100vh"; psbd.insertBefore(nl, blct); dfi.setAttribute("style", "clear:both;"); npsbd.appendChild(dfi); npsbd.insertAdjacentHTML("afterbegin", blct.innerText);
Qooqなどの非公式テーマは他のソースコードの関係から遅延読み込みのソースコードが使えない場合もあるかも知れません。
お教えいただいた3点をひとつずつ適用して、動作確認用のポップアップとPageSpeed Insights での「オフスクリーン画像を遅延読み込みする」をみましたが、やはり効いていないようです。
削除さらに、素のQooQ(Version:2.00)を入手して、このプログラムを導入してみましたが、効いていないようです。
この記事では省略しましたが、レイアウトヴァージョン2のテンプレートは「 <data:post.body/>」を含む記事のためのソースコードがパソコン用とスマホ用の二つに分かれています(詳細)。
削除前回のQooqのソースコードを見ると公式テーマのレイアウトヴァージョン2のスマホ用と同じです。なのでパソコン用に次のようなソースコードもあるかも知れません。
<div class='post-body entry-content' expr:id='"post-body-" + data:post.id' expr:itemprop='(data:blog.metaDescription ? "" : "description ") + "articleBody"'>
<data:post.body/>
<div style='clear: both;'/> <!-- clear for photos floats -->
</div>
通常はこちらの「<data:post.body/>」をカスタマイズしてテンプレートをスマホに対応させる場合はもう一つの「<data:post.body/>」もカスタマイズするようにします。
公式テーマだとレイアウトヴァージョン2のパソコン用の「<data:post.body/>」はスマホ用のもっと先にありますので、Qooqも二つに分かれてないかどうかを確認してみて下さい。
うまく動くようになりました。ポップアップとPageSpeedで確認しました。
削除が2か所にあることには気づいていましたが、導入例に比べて下記に載せたように構文が簡素だったこととから、そちらは気に留めていませんでした。記事をもっとしっかりと読み込むべきでした。
ご指摘いただいたように、もう一か所ののところを書き換えると、画像遅延が有効になりました。”遅延読み込み用ソースコード” の特殊文字を通常文字に戻す変更は適用していません。
手厚いご教授をいただき、本当にありがとうございました。
”遅延読み込み用ソースコード” は同じものを2か所に入れたのですが、これでよかったのでしょうか。
[[QooQ オリジナル]]
<div class='post-body' id='single-content'>
<data:post.body/>
<div style='clear: both;'/> <!-- clear for photos floats -->
</div>
[[書き換え 2か所目]]
<div class='post-body' id='single-content'>
<b:tag cond='data:view.featuredImage' class='blog-content' name='noscript'><data:post.body/></b:tag>
<div style='clear: both;'/> <!-- clear for photos floats -->
</div>
<b:if cond='data:view.featuredImage'>
<script>
遅延読み込み用ソースコード
</script>
</b:if>
正常に動作して良かったです。
削除遅延読み込みのソースコードはパソコンとスマホで同じものを使うことができます。
振り分けのcond属性はパソコン用とスマホ用が同じでも大丈夫ですけど、スマホ用の本文のソースコードは最初から記事/追加ページの専用ですから「data:view.featuredImage」だけでも画像なしのページを適切に除外できます。
因みにレイアウトヴァージョン2のスマホ対応は公式テーマの場合は自動化されてません。
Qooqも同じならばBloggerの管理画面のテーマのメニュー(カスタマイズの右横の▽)の「モバイルの設定」をモバイルの「カスタム」(パソコンと同じものをカスタマイズして使う場合)にしないとスマホで閲覧してもパソコン用のソースコードが適用されますので、注意して下さい。