1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-08-26 17:54:52 +02:00

improved lazy loading

This commit is contained in:
Pomax
2020-09-13 13:18:15 -07:00
parent a626c2c8cb
commit c0a1207d67
27 changed files with 163 additions and 208 deletions

View File

@@ -0,0 +1,38 @@
/**
* 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 (mostly) prevents the whole "you can see the image
* loading in", which is super shitty UX.
*/
const images = Array.from(
document.querySelectorAll(`img.LaTeX.SVG[loading=lazy]`)
);
// Deactivate the images
images.forEach((img) => {
img.dataset.src = img.src;
img.src = ``;
img.removeAttribute(`loading`);
});
// Then make their activation conditional on whether
// they're close to being on-screen or not.
let observer = new IntersectionObserver(
function (entries) {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
const pos = images.indexOf(img);
images.splice(pos, 1);
}
});
},
{ rootMargin: `100%` }
);
images.forEach((image) => {
observer.observe(image);
});

View File

@@ -1,17 +1,13 @@
const comments = document.getElementById(`disqus_thread`);
document.addEventListener("scroll", scrollHandler, { passive: true });
function scrollHandler() {
var bbox = comments.getBoundingClientRect();
var top = bbox.top;
var limit = window.innerHeight;
if (top < limit) {
loadDisqus();
}
}
new IntersectionObserver(function (entries) {
entries.forEach((entry) => {
if (entry.isIntersecting) {
loadDisqus();
}
});
}).observe(document.getElementById(`disqus_thread`));
let loadDisqus = () => {
loadDisqus = () => {};
console.log(`loading Disqus comments`);
globalThis.disqus_config = function () {
@@ -24,9 +20,4 @@ let loadDisqus = () => {
script.async = true;
script.setAttribute("data-timestamp", Date.now());
document.head.appendChild(script);
loadDisqus = () => {};
document.removeEventListener("scroll", scrollHandler);
};
scrollHandler();

View File

@@ -1,77 +0,0 @@
/**
* 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.LaTeX.SVG[loading=lazy]`)
);
// 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 height = document.documentElement.clientHeight;
for (let pos = images.length - 1; pos >= 0; pos--) {
test(images[pos], pos, 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, height) {
let top = img.getBoundingClientRect().top;
top = top < height;
let bottom = img.getBoundingClientRect().bottom;
bottom = bottom > -height;
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 });