Bloggerの記事/追加ページの投稿画像や動画に遅延読み込みのHTML属性のloading-lazyを自動的に付けるJavaScriptプログラムの内容を説明する。
JavaScript
// 記事の本文の要素(psbd)と記事の本文の中身に付けたnoscript要素(blct)と記事の本文の要素の複製(npsbd)と新しいdiv要素(nl)の取得
const psbd = Blog1.querySelector("div.post-body"), blct = psbd.querySelector("noscript.blog-content"), npsbd = psbd.cloneNode(false), nl = document.createElement("div");
// 新しいdiv要素の高さを画面の縦幅と同じにする
nl.style.height = "100vh";
// 新しいdiv要素をnoscript要素の前に挿入する(無地の画面が最初に素早く出るようにしてプログラムの実行で記事の表示が遅れた際の違和感を減らすため)
psbd.insertBefore(nl, blct);
// 記事の本文の複製にnoscript要素のソースコードを入れる(noscript要素のソースコードはテキストだからそのままではHTMLとして扱えないため)
npsbd.insertAdjacentHTML("afterbegin", blct.innerText);
// 記事の本文の複製から画像要素を取得
const blimgs = npsbd.querySelectorAll("img");
// 画像の場合(画像か動画ありで振り分け済みの記事の本文から動画を除外するため/遅延読み込みに動画を含めるならば不要)
if (blimgs[0]) {
// 画像の配列をPromise.allとmapで並列処理
Promise.all([...blimgs].map(blimg => {
// 画像の縦横比(aroi)の取得
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; }
// 縦幅も横幅もなくて縦横比があってCSSの縦横比の指定のaspect-ratioがない場合、画面の横幅に対する画像の縦幅を算出して画像の位置(ブログの最上段からの距離)を推測するためにCSSのaspect-ratioを付ける
else if (aroi && !blimg.style.aspectRatio) {
blimg.style.aspectRatio = aroi; }
// 画像のalt属性が空だったら「イメージ」(日本語の場合)を記載する(Google検索のサイト評価のモバイルユーザビリティの警告を避けるため)
if (!blimg.alt) blimg.alt = "<data:messages.image/>";
// 画像要素のURLをカスタムデータへ移動してsrc属性から取り除いて画像要素を次のthen関数へ渡す
blimg.dataset.src = blimg.src; blimg.src = "": return blimg; })).then(results => {
// 記事の本文の複製を元の記事の本文(中身がnoscriptタグで止められたもの)と入れ換える(画像の位置を把握するために記事の本文を表示させるが、この時点ではsrc属性が空だから画像は読み込まれない)
psbd.parentNode.replaceChild(npsbd, psbd);
// 画像の配列をforEachで繰り返し処理
results.forEach(result => {
// 画像の上側が画面の高さと同じかそれよりも大きい(画面に表示されない位置にあるかあると推測される)場合、loading属性のlazyを付ける
if (result.getBoundingClientRect().top >= window.innerHeight)
result.loading = "lazy";
// 画像要素のsrc属性にカスタムデータのURLを移動して画像の読み込みを可能にして(loading-lazyを付けたものは画面に入るまで読み込まれない)カスタムデータを空にする。
result.src = result.dataset.src; delete result.dataset.src; }); }); }
// 動画の場合(遅延読み込みに動画を含めるならば不要)、記事の本文の複製を元の記事の本文(中身がnoscriptタグで止められたもの)と入れ換える(記事の本文が全て表示される)
else {
psbd.parentNode.replaceChild(npsbd, psbd); }
出典:Bloggerの記事/追加ページの投稿画像にloading-lazyを自動的に付けるプログラム
参考:画像のloading-lazy:遅延読み込みによる高速化について