Greasy Fork is available in English.
Optimize image loading by adding lazy loading, WebP support, and concurrent requests.
当前为
// ==UserScript==
// @name Webp图片加载优化
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Optimize image loading by adding lazy loading, WebP support, and concurrent requests.
// @author KiwiFruit
// @match *://*/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 检查浏览器是否支持WebP格式
function supportsWebP(callback) {
const webP = new Image();
webP.src = 'data:image/webp;base64,UklGRi4AAABXRUJQVlA4TCEAAAAvAUAAEB8wAiMw' +
'AgSSNtse/cXjxyCCmrYNWPwmHRH9jwMA';
webP.onload = webP.onerror = () => callback(webP.height === 2);
}
// 替换图片元素的src属性为对应的WebP版本
function replaceWithWebP(imageElement, src) {
supportsWebP((supports) => {
if (supports) {
// 尝试将图片路径转换为WebP格式
const webpSrc = src.replace(/\.(jpg|jpeg|png)$/, '.webp');
fetch(webpSrc)
.then(response => {
// 如果响应成功,则设置图片的src为WebP版本
if (response.ok) {
imageElement.src = webpSrc;
} else {
// 如果响应失败,则回退到原始图片路径
imageElement.src = src;
}
})
.catch(() => {
// 在fetch请求出错的情况下,也回退到原始图片路径
imageElement.src = src;
});
} else {
// 如果不支持WebP,则直接使用原始图片路径
imageElement.src = src;
}
});
}
// 并发加载一组图片URL
function loadImages(imageUrls) {
return Promise.all(imageUrls.map(url =>
new Promise((resolve, reject) => {
const img = new Image();
img.src = url;
img.onload = () => resolve(img);
img.onerror = () => reject(new Error(`Failed to load ${url}`));
})
));
}
// 设置动态加载机制
function setupDynamicLoading(images) {
let observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
observer.unobserve(img);
replaceWithWebP(img, img.getAttribute('data-src'));
}
});
}, { threshold: 0.1 });
images.forEach(img => observer.observe(img));
}
// 预加载首屏可见区域内的图片
function preloadFirstScreenImages(images) {
const visibleImages = Array.from(images).filter(img => {
const rect = img.getBoundingClientRect();
return rect.top >= 0 && rect.bottom <= window.innerHeight;
});
const imageUrls = visibleImages.map(img => img.getAttribute('data-src'));
loadImages(imageUrls).then(() => setupDynamicLoading(images));
}
// 监听DOMContentLoaded事件确保DOM完全构建后再执行
document.addEventListener('DOMContentLoaded', () => {
const images = document.querySelectorAll('img[data-src]');
if (images.length > 0) {
preloadFirstScreenImages(images);
}
});
})();