Update Image Loader Placeholder Remover to 1.23.2
- *Actually* fix page slowdowns by ferociously caching CSS properties
This commit is contained in:
parent
9a64f71505
commit
ed2fbde27a
|
@ -4,7 +4,7 @@
|
|||
// @match http*://*/*
|
||||
// @exclude-match http*://solar.lowtechmagazine.com/*
|
||||
// @grant none
|
||||
// @version 1.23.1
|
||||
// @version 1.23.2
|
||||
// @author blankie
|
||||
// @run-at document-end
|
||||
// @description Removes image loading placeholders
|
||||
|
@ -18,25 +18,21 @@ const URL_RE = new RegExp(`^${URL_RE_STR}$`);
|
|||
const SRCSET_COMPONENT = `${URL_RE_STR}(?:\\s+\\d+w|\\s+\\d+(?:\\.\\d+)?x)?`;
|
||||
const SRCSET_RE = new RegExp(`^${SRCSET_COMPONENT}(?:,\\s*${SRCSET_COMPONENT})*$`);
|
||||
|
||||
let cachedCSSProperties = new Map();
|
||||
|
||||
function isUrlLike(url) {
|
||||
// Example of ./path:
|
||||
// - https://projects.apnews.com/features/2023/missing-students-chronic-absenteeism/index.html
|
||||
return url && URL_RE.test(url);
|
||||
}
|
||||
function findUrl(element) {
|
||||
if (window.location.host === "www.vice.com") {
|
||||
let picture = element.parentElement;
|
||||
let source = picture && picture.localName === "picture" ? picture.querySelector("source") : null;
|
||||
if (source) {
|
||||
return source.srcset;
|
||||
}
|
||||
}
|
||||
|
||||
function getUrlAttributes(element) {
|
||||
let attributes = [];
|
||||
|
||||
// https://blog.google/
|
||||
// https://blog.google/threat-analysis-group/active-north-korean-campaign-targeting-security-researchers/
|
||||
if (window.location.host === "blog.google" && element.hasAttribute("data-loading")) {
|
||||
let data = JSON.parse(element.getAttribute("data-loading"));
|
||||
return data.desktop || data.mobile;
|
||||
attributes.push(element.getAttributeNode("data-loading"));
|
||||
}
|
||||
|
||||
// Examples of data-src:
|
||||
|
@ -51,7 +47,7 @@ function findUrl(element) {
|
|||
// - https://knowyourmeme.com/
|
||||
// - https://knowyourmeme.com/memes/saddam-husseins-hiding-place
|
||||
if (isUrlLike(element.dataset.src)) {
|
||||
return element.dataset.src;
|
||||
attributes.push(element.getAttributeNode("data-src"));
|
||||
}
|
||||
|
||||
for (let attr of element.attributes) {
|
||||
|
@ -79,7 +75,31 @@ function findUrl(element) {
|
|||
if (!isUrlLike(attr.value)) {
|
||||
continue;
|
||||
}
|
||||
return attr.value;
|
||||
attributes.push(attr);
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
function findUrl(element) {
|
||||
if (window.location.host === "www.vice.com") {
|
||||
let picture = element.parentElement;
|
||||
let source = picture && picture.localName === "picture" ? picture.querySelector("source") : null;
|
||||
if (source) {
|
||||
return source.srcset;
|
||||
}
|
||||
}
|
||||
|
||||
// https://blog.google/
|
||||
// https://blog.google/threat-analysis-group/active-north-korean-campaign-targeting-security-researchers/
|
||||
if (window.location.host === "blog.google" && element.hasAttribute("data-loading")) {
|
||||
let data = JSON.parse(element.getAttribute("data-loading"));
|
||||
return data.desktop || data.mobile;
|
||||
}
|
||||
|
||||
let urlAttributes = getUrlAttributes(element);
|
||||
if (urlAttributes.length !== 0) {
|
||||
return urlAttributes[0].value;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -98,6 +118,17 @@ function findSrcset(element) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function getCachedCSSProperties(element, key) {
|
||||
if (cachedCSSProperties.has(key)) {
|
||||
return cachedCSSProperties.get(key);
|
||||
}
|
||||
|
||||
let {opacity, display, visibility, filter} = getComputedStyle(element);
|
||||
let ret = {opacity, display, visibility, filter};
|
||||
cachedCSSProperties.set(key, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
function getLazyloaderClasses(element) {
|
||||
let classes = [];
|
||||
|
||||
|
@ -172,6 +203,7 @@ function cloneLazyloaderTree(element, elementLazyLoaderClasses) {
|
|||
for (let attr of getLazyloaderAttributes(followingTopMostParent)) {
|
||||
clone.setAttribute(attr.name, attr.value);
|
||||
}
|
||||
|
||||
if (topMostParent) {
|
||||
clone.append(topMostParent);
|
||||
}
|
||||
|
@ -185,8 +217,12 @@ function cloneLazyloaderTree(element, elementLazyLoaderClasses) {
|
|||
|
||||
let clone = document.createElement(element.localName);
|
||||
clone.classList.add(...elementLazyLoaderClasses);
|
||||
let urlAttributeNames = new Set(["src", "href"]);
|
||||
for (let attr of getUrlAttributes(element)) {
|
||||
urlAttributeNames.add(attr.name);
|
||||
}
|
||||
for (let attr of getLazyloaderAttributes(element)) {
|
||||
clone.setAttribute(attr.name, attr.value);
|
||||
clone.setAttribute(attr.name, !urlAttributeNames.has(attr.name) ? attr.value : "");
|
||||
}
|
||||
|
||||
if (bottomMostChild) {
|
||||
|
@ -200,9 +236,19 @@ function cloneLazyloaderTree(element, elementLazyLoaderClasses) {
|
|||
}
|
||||
|
||||
function unhideElement(element, lazyLoaderClasses) {
|
||||
let style = getComputedStyle(element);
|
||||
// We no longer/don't check the styles of each element individually, but rather their "generified" version
|
||||
// (i.e., only lazy classes), because checking each actual element causes a lot of cache busts
|
||||
|
||||
// Examples of opacity:
|
||||
// We check if the classes discriminate lazyloaded images, just in case
|
||||
// We can't remove the lazyload classes from the image, because:
|
||||
// - https://legendsoflocalization.com/japans-mysterious-love-of-the-word-lets/#why-lets-is-so-common
|
||||
// - https://www.wired.com/story/why-do-printers-still-suck/
|
||||
// However, some sites use the classes to blur and/or change the opacity of images
|
||||
let [toRemove, toExamine] = cloneLazyloaderTree(element, lazyLoaderClasses);
|
||||
document.body.append(toRemove);
|
||||
let classStyle = getCachedCSSProperties(toExamine, toRemove.outerHTML);
|
||||
|
||||
// Examples of opacity === "0":
|
||||
// - https://closeronline.co.uk
|
||||
// - https://closeronline.co.uk/real-life/news/ever-used-excuses-documented-spreadsheet-man-used-expose-wife-s-lack-sex
|
||||
// - https://www.vice.com/en/article/dy73n7/ehallpass-1000-thousand-schools-monitor-bathroom
|
||||
|
@ -210,14 +256,16 @@ function unhideElement(element, lazyLoaderClasses) {
|
|||
// - https://daramiblog.com/how-to-group-irregular-verbs-for-more-efficient-learning/
|
||||
// - https://www.wired.com/
|
||||
// - https://www.wired.com/story/researcher-fooled-a-google-ai-into-thinking-a-rifle-was-a-helicopter/
|
||||
if (style.opacity === "0") {
|
||||
// Example of opacity === "0.75":
|
||||
// https://www.404media.co/welcome-to-404-media/
|
||||
if (classStyle.opacity !== "1") {
|
||||
element.style.opacity = 1;
|
||||
}
|
||||
|
||||
// Examples of display:
|
||||
// - https://closeronline.co.uk
|
||||
// - https://closeronline.co.uk/real-life/news/ever-used-excuses-documented-spreadsheet-man-used-expose-wife-s-lack-sex
|
||||
if (style.display === "none") {
|
||||
if (classStyle.display === "none") {
|
||||
element.style.display = "block";
|
||||
}
|
||||
|
||||
|
@ -226,16 +274,6 @@ function unhideElement(element, lazyLoaderClasses) {
|
|||
element.style.paddingBottom = 0;
|
||||
}
|
||||
|
||||
// We check if the classes discriminate lazyloaded images, just in case
|
||||
// We can't remove the lazyload classes from the image, because:
|
||||
// - https://legendsoflocalization.com/japans-mysterious-love-of-the-word-lets/#why-lets-is-so-common
|
||||
// - https://www.wired.com/story/why-do-printers-still-suck/
|
||||
// However, some sites use the classes to blur and/or change the opacity of images
|
||||
|
||||
let [toRemove, toExamine] = cloneLazyloaderTree(element, lazyLoaderClasses);
|
||||
document.body.append(toRemove);
|
||||
let classStyle = getComputedStyle(toExamine);
|
||||
|
||||
// Examples of visibility:
|
||||
// - https://www.edinburghlive.co.uk/
|
||||
// - https://www.edinburghlive.co.uk/news/edinburgh-news/edinburgh-couple-fume-handed-17k-27906242
|
||||
|
@ -243,12 +281,6 @@ function unhideElement(element, lazyLoaderClasses) {
|
|||
element.style.visibility = "visible";
|
||||
}
|
||||
|
||||
// Example of opacity === "0.75":
|
||||
// https://www.404media.co/welcome-to-404-media/
|
||||
if (classStyle.opacity !== "1") {
|
||||
element.style.opacity = 1;
|
||||
}
|
||||
|
||||
// Examples of blur:
|
||||
// - https://www.404media.co/welcome-to-404-media/
|
||||
// - https://restofworld.org/
|
||||
|
@ -350,15 +382,15 @@ function removePlaceholder(img) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
for (let img of Array.from(document.querySelectorAll("img"))) {
|
||||
for (let img of document.querySelectorAll("img")) {
|
||||
removePlaceholder(img);
|
||||
}
|
||||
// the reason we reunhide images after 1s after the page loads is because of <noscript> elements being faked by umatrix
|
||||
setTimeout(function() {
|
||||
for (let img of Array.from(document.querySelectorAll("img")) {
|
||||
for (let img of document.querySelectorAll("img")) {
|
||||
removePlaceholder(img);
|
||||
}
|
||||
cachedCSSProperties.clear();
|
||||
}, 1000);
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue