Improvements to Lazy Loading
- Now applied to all images over 150x150px - Stores the width and height in the WeakMap rather than using percentages for accuracy - When oneboxed images are hidden, they are given a subtle border for better visibility. - Don't apply when in the composer. Causes flickering.
This commit is contained in:
parent
7feabd9e49
commit
0e710dc573
|
@ -2,7 +2,10 @@ const OBSERVER_OPTIONS = {
|
||||||
rootMargin: "50%" // load images slightly before they're visible
|
rootMargin: "50%" // load images slightly before they're visible
|
||||||
};
|
};
|
||||||
|
|
||||||
const imageSources = new WeakMap();
|
// Min size in pixels for consideration for lazy loading
|
||||||
|
const MINIMUM_SIZE = 150;
|
||||||
|
|
||||||
|
const hiddenData = new WeakMap();
|
||||||
|
|
||||||
const LOADING_DATA =
|
const LOADING_DATA =
|
||||||
"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
|
"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
|
||||||
|
@ -12,7 +15,12 @@ function hide(image) {
|
||||||
image.classList.add("d-lazyload");
|
image.classList.add("d-lazyload");
|
||||||
image.classList.add("d-lazyload-hidden");
|
image.classList.add("d-lazyload-hidden");
|
||||||
|
|
||||||
imageSources.set(image, { src: image.src, srcset: image.srcset });
|
hiddenData.set(image, {
|
||||||
|
src: image.src,
|
||||||
|
srcset: image.srcset,
|
||||||
|
width: image.width,
|
||||||
|
height: image.height
|
||||||
|
});
|
||||||
image.removeAttribute("srcset");
|
image.removeAttribute("srcset");
|
||||||
|
|
||||||
image.src = image.dataset.smallUpload || LOADING_DATA;
|
image.src = image.dataset.smallUpload || LOADING_DATA;
|
||||||
|
@ -21,9 +29,9 @@ function hide(image) {
|
||||||
|
|
||||||
// Restore an image when onscreen
|
// Restore an image when onscreen
|
||||||
function show(image) {
|
function show(image) {
|
||||||
let sources = imageSources.get(image);
|
let imageData = hiddenData.get(image);
|
||||||
|
|
||||||
if (sources) {
|
if (imageData) {
|
||||||
const copyImg = new Image();
|
const copyImg = new Image();
|
||||||
copyImg.onload = () => {
|
copyImg.onload = () => {
|
||||||
image.src = copyImg.src;
|
image.src = copyImg.src;
|
||||||
|
@ -35,14 +43,14 @@ function show(image) {
|
||||||
copyImg.onload = null;
|
copyImg.onload = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
copyImg.src = sources.src;
|
copyImg.src = imageData.src;
|
||||||
copyImg.srcset = sources.srcset || copyImg.srcset;
|
copyImg.srcset = imageData.srcset || copyImg.srcset;
|
||||||
|
|
||||||
copyImg.style.position = "absolute";
|
copyImg.style.position = "absolute";
|
||||||
copyImg.style.top = 0;
|
copyImg.style.top = 0;
|
||||||
copyImg.style.left = 0;
|
copyImg.style.left = 0;
|
||||||
copyImg.style.height = "100%";
|
copyImg.style.width = imageData.width;
|
||||||
copyImg.style.width = "100%";
|
copyImg.style.height = imageData.height;
|
||||||
|
|
||||||
image.parentNode.appendChild(copyImg);
|
image.parentNode.appendChild(copyImg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -62,10 +70,15 @@ export function setupLazyLoading(api) {
|
||||||
});
|
});
|
||||||
}, OBSERVER_OPTIONS);
|
}, OBSERVER_OPTIONS);
|
||||||
|
|
||||||
api.decorateCooked($post => {
|
api.decorateCooked(
|
||||||
$(".lightbox img", $post).each((_, img) => {
|
$post => {
|
||||||
hide(img);
|
$("img", $post).each((_, img) => {
|
||||||
observer.observe(img);
|
if (img.width >= MINIMUM_SIZE && img.height >= MINIMUM_SIZE) {
|
||||||
});
|
hide(img);
|
||||||
});
|
observer.observe(img);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ onlyStream: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,10 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.onebox img.d-lazyload-hidden {
|
||||||
|
border: 1px solid $primary-low;
|
||||||
|
}
|
||||||
|
|
||||||
.cooked img.d-lazyload {
|
.cooked img.d-lazyload {
|
||||||
transition: opacity 0.4s 0.75s ease;
|
transition: opacity 0.4s 0.75s ease;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue