1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-29 02:59:58 +02:00

canonical

This commit is contained in:
Pomax
2020-08-21 15:32:49 -07:00
parent 8dce6aed6b
commit c90565f493
227 changed files with 1899 additions and 590 deletions

View File

@@ -0,0 +1,76 @@
/**
* This file takes any <img> with loading="lazy" and rewrites it
* so that it starts to load much earlier than browsers would load
* them, so that they're already done by the time the user gets to
* them. This prevents the ridiculous "don't start loading the img
* until we're already looking at the empty bounding box".
*/
const images = Array.from(
document.querySelectorAll(`img[loading=lazy]`)
).filter((img) => img.parentNode.nodeName !== `FALLBACK-IMAGE`);
// First, make images inert. As this happens before the document
// becomes active, this prevents images from loading anything.
//
// Also, by having JS deactivate the images, anyone running with
// JS disabled will still see images load in properly. In fact,
// the "lazy" attribute gets ignored when JS is disabled and all
// images will just load in immediately.
images.forEach((img) => {
// non-negotiable order of operations:
img.dataset.src = img.src;
img.src = ``;
img.removeAttribute(`loading`);
});
// Then tack on the functionality that reactivates them based on viewport distance.
let lock = false;
let retry = false;
/**
* Test all images during scroll, in a way that doesn't hang the browser.
*/
function testImages() {
if (lock) {
if (retry) retry = clearTimeout(retry);
retry = setTimeout(testImages, 200);
}
lock = true;
let top = window.scrollY;
let height = document.documentElement.clientHeight;
let bottom = top + height;
for (let pos = images.length - 1; pos >= 0; pos--) {
test(images[pos], pos, top, bottom, height);
}
if (images.length === 0) {
window.removeEventListener("scroll", testImages);
if (retry) clearTimeout(retry);
}
lock = false;
}
/**
* Test individual images for whether or not they should load.
*/
function test(img, pos, top, bottom, threshold) {
top = Math.abs(img.offsetTop - top) < threshold;
bottom = Math.abs(img.offsetTop + img.offsetHeight - bottom) < threshold;
if (top || bottom) {
img.src = img.dataset.src;
images.splice(pos, 1);
}
}
/**
* Remember to listen for scroll passively. If you don't, bad things happen.
*/
window.addEventListener("scroll", testImages, { passive: true });