目次
1️⃣ はじめに
loading="lazy"
は画像の遅延読み込みを自動的に処理する便利な機能ですが、ブラウザの制御に依存するため、意図しない動作を引き起こすことがあります。
今回紹介する lazyload-prioritize.js
は、通常の画像がすべて読み込まれた後に、loading="lazy"
を適用した画像を ビューポートに近い順 に優先的に読み込むスクリプトです。
2️⃣ コードの解説
📌 スクリプトの全体像
lazyload-prioritize.js
document.addEventListener("DOMContentLoaded", () => {
console.log("スクリプト開始: lazyload-prioritize.js");
const lazyImages = document.querySelectorAll("img[loading='lazy']");
const normalImages = document.querySelectorAll("img:not([loading='lazy'])");
let normalImagesLoaded = 0;
console.log(`通常画像の数: ${normalImages.length}`);
console.log(`Lazy画像の数: ${lazyImages.length}`);
function checkNormalImagesLoaded() {
console.log(`読み込まれた通常画像数: ${normalImagesLoaded} / ${normalImages.length}`);
if (normalImagesLoaded === normalImages.length) {
console.log("すべての通常画像が読み込まれました!Lazy画像の優先読み込みを開始します。");
prioritizeLazyImages();
}
}
// **通常画像のロード完了をカウント**
normalImages.forEach(img => {
if (img.complete) {
console.log(`すでに読み込まれている画像: ${img.src}`);
normalImagesLoaded++;
} else {
img.onload = () => {
normalImagesLoaded++;
console.log(`読み込み完了: ${img.src}`);
checkNormalImagesLoaded();
};
img.onerror = () => {
console.warn(`読み込み失敗: ${img.src}`);
normalImagesLoaded++; // 失敗してもカウントを進める
checkNormalImagesLoaded();
};
}
});
// **ビューポートに近いLazy画像から優先的に読み込む**
function prioritizeLazyImages() {
if (lazyImages.length === 0) {
console.log("Lazy画像がありません。処理を終了します。");
return;
}
const distances = [];
// **すべてのLazy画像のビューポートからの距離を計算**
lazyImages.forEach(img => {
const rect = img.getBoundingClientRect();
const distance = Math.abs(rect.top); // ビューポートの上からの距離
distances.push({ img, distance });
});
// **距離が近い順にソート**
distances.sort((a, b) => a.distance - b.distance);
// **距離が近い順に画像をロード**
distances.forEach(({ img }, index) => {
setTimeout(() => {
console.log(`優先読み込み開始: ${img.src}`);
img.removeAttribute("loading"); // lazy を削除
img.src = img.src; // 強制リロード
}, index * 100); // 100ms 間隔で順番に読み込み
});
}
// **ページロード時に通常画像がすでに読み込まれているかチェック**
checkNormalImagesLoaded();
});
📌 コードのポイント
1️⃣ 通常の画像を監視し、すべて読み込まれたら lazy
画像の処理を開始
通常の画像 (loading="lazy"
が付いていないもの) の読み込みが完了するまで待機します。
normalImages.forEach(img => {...})
で通常の画像を監視し、すべての画像が読み込まれたらprioritizeLazyImages()
を実行します。
2️⃣ loading="lazy"
の画像をビューポートに近い順にロード
lazyImages.forEach(img => {...})
で各画像の ビューポートの上からの距離 (rect.top
) を計算し、近い順にソート します。
setTimeout()
を使い、100ms 間隔 で順番に画像を読み込むことで、急激なリソースの増加を防ぎます。img.removeAttribute("loading")
により、loading="lazy"
を解除し、即時ロードを可能にします。
3️⃣ 読み込みエラー対策
画像の読み込みに失敗した場合でも onerror
でカウントを進め、処理が止まらないようにしています。
3️⃣ このスクリプトのメリット
✅ 通常の画像がすべて読み込まれてから lazy
画像を優先的にロード
✅ スクロール前に表示するべき画像が適切にロードされる
✅ ビューポートに近い画像から優先的に読み込むため UX が向上
✅ 急激なリソースの消費を防ぎ、スムーズなページ読み込みを維持
4️⃣ まとめ
このスクリプトを導入することで、loading="lazy"
の画像をより効果的に制御し、ページの表示速度を最適化できます。
loading="lazy"
を そのまま適用するだけでは UX や SEO に悪影響を及ぼす可能性 がありますが、本スクリプトを導入することで、
- 通常画像の読み込みを優先し、Lazy Load の画像を適切に制御
- ビューポートに近い画像から優先的にロードすることで UX を向上
することができます。
あわせて読みたい


ページがインデックスに登録されなかった理由 – 見つかりませんでした(404)が激増したお話し
突然 SearchConsole で、見つかりませんでした(404)が激増した 実際に存在しない https://officeueda.com/shopdetail/* が激増してる https://officeueda.com/shopdet…