すたすた式
Blogger QooQ
試験的にトップページの投稿(記事)サムネイルをJavaScriptのIntersectionObserverを使って遅延読み込みしてみました。
IntersectionObserver
サムネイルが見えている領域にも適用されるので、もう一工夫必要かなと考えています。
自分の環境ではあまりパフォーマンスに変化はありませんでしたが、記録として残しておきます。
QooQ ver.2.00を例にします。(list版はHTMLの構成が少し違いますがやることは一緒です)
HTMLを編集します。必ずバックアップを取ってから作業してください。
下記を変更します。
<img class='list-item-img' expr:src='resizeImage(data:post.firstImageUrl, 480, "2:1")' height='240' width='480'/>
変更箇所
expr:src
expr:data-src
src=''
<noscript>
↓ ↓ ↓
<img class='list-item-img' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NgAAIAAAUAAR4f7BQAAAAASUVORK5CYII=' expr:data-src='resizeImage(data:post.firstImageUrl, 480, "2:1")' height='240' width='480'/>
decoding='async'を付与してもいいかもしれません。
decoding='async'
<img class='list-item-img' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NgAAIAAAUAAR4f7BQAAAAASUVORK5CYII=' expr:data-src='resizeImage(data:post.firstImageUrl, 480, "2:1")' height='240' width='480' decoding='async'/>
1pxサイズの透過した画像は、1px の画像データURLメモのジェネレーターアプリ、1px data url generatorで作成しました。
<b:if cond='data:view.isMultipleItems'> <script> //<![CDATA[ "use strict"; (() => { // 交差を監視する要素 const images = document.getElementsByClassName("list-item-img"); const arrayImages = Array.from(images); // オプション const options = { // ルート要素(無ければviewport) root: null, // 0pxで実行 rootMargin: "0px", // 交差領域に入ったら実行 threshold: 0, }; // 初期化 const observer = new IntersectionObserver(lazyArticlesThumbnail, options); arrayImages.forEach((img) => { // 監視を開始 observer.observe(img); }); // コールバック function lazyArticlesThumbnail(entries, object) { entries.forEach((entry) => { // 交差していない場合はプログラム終了 if (!entry.isIntersecting) return; // ターゲット要素 let img = entry.target; // data-srcのパスをsrcに設定 img.src = img.dataset.src; // 監視を解除 object.unobserve(img); }); } })(); //]]> </script> </b:if>
JavaScriptの設置場所は</body>の上あたりでいいと思います。
</body>
※推測ですが早く実行させたければ<div id='list'>の終了タグ手前に設置するのもありかもしれません。
<div id='list'>
<div id='list'> <b:loop values='data:posts' var='post'> <b:include data='post' name='post'/> </b:loop> <!--ここに設置--> </div>
オプションはデフォルト値なのでなくてもいいのですが、一応付けておきました。
querySelectorAll();はgetElementsByClassName();に比べて遅いということなので、要素の検索にgetElementsByClassName();を使いました。それにともないforEachを使いたかったのでArray.from();で配列にしました。
querySelectorAll();
getElementsByClassName();
forEach
Array.from();
jQueryのクラスセレクタは約8~11倍、getElementByIdより遅いことがあるぞ (DOMを10,000回取得しただけ) - Qiita
querySelectorAll();を使う場合はArray.from();はいりません。
検索範囲を狭くする狙いでdocument.getElementsByClassName("list-item-img");をBlog1.getElementsByClassName("list-item-img");にしました。
document.getElementsByClassName("list-item-img");
Blog1.getElementsByClassName("list-item-img");
<b:if cond='data:view.isMultipleItems'>でトップページ、ラベル、アーカイブ、検索でプログラムが実行します。適宜変更するか、必要なければ削除してください。
<b:if cond='data:view.isMultipleItems'>
<b:if cond='data:view.isMultipleItems'> </b:if>
IntersectionObserver - Web API | MDN
IntersectionObserver.IntersectionObserver() - Web API | MDN
JSでのスクロール連動エフェクトにはIntersection Observerが便利 - ICS MEDIA
使ってみよう!Intersection Observer! - Qiita
当初、1pxの透過したダミー画像はWindowsのペイントを使って1px × 1pxの白のpng画像を作成。
画像透過:背景透過・PNG対応 | ラッコツールズ🔧で透過したものを使用。
他の透過ツール候補【2022】透過PNGを手軽に作成できるツール7選と使い方 - BGremover
(案)サムネイルが見えている領域は通常通りに書き出して、見えない領域だけ遅延読み込み
見えない領域用のb:includableタグを新しく作成。
b:includable
<b:includable id='lazyPost' var='post'> <!-- サムネイルが見えない領域のコード --> </b:includable>
目視で見えているサムネイルを数えてindex="i"とdata:iを使ってb:ifタグで条件分岐。
index="i"
data:i
b:if
<div id='list'> <b:loop values='data:posts' var='post'> <b:include data='post' name='post'/> </b:loop> </div> ↓ <div id='list'> <b:loop values='data:posts' var='post' index='i'> <b:if cond='data:i + 1 lte 3'> <b:include data='post' name='post'/> <b:else/> <b:include data='post' name='lazyPost'/> </b:if> </b:loop> </div>
(PageSpeed InsightsやLighthouseはMoto G4のサイズで判定しているので)デベロッパーツールで見えているサムネイルを数えるときはMoto G4にしておく。
サイト内検索に使ってください 🐤
© 2015 すたすた式
Enjoy!👍
QooQ
コメントなし:
コメントを投稿