// ==UserScript== // @name Webp图片加载优化 // @namespace http://tampermonkey.net/ // @version 1.0 // @description Optimize image loading by adding lazy loading, WebP support, and concurrent requests. // @author KiwiFruit // @match *://*/* // @grant none // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // 检查浏览器是否支持WebP function supportsWebP(callback) { const webP = new Image(); webP.src = 'data:image/webp;base64,UklGRi4AAABXRUJQVlA4TCEAAAAvAUAAEB8wAiMwMAAgH8JeYW5kZXI='; webP.onload = webP.onerror = function () { callback(webP.height === 2); }; } // 动态替换为WebP图片(如果有) function replaceWithWebP(imageElement, src) { const webPSrc = src.replace(/\.(jpg|jpeg|png)$/, '.webp'); const img = new Image(); img.src = webPSrc; img.onload = function() { imageElement.src = webPSrc; }; img.onerror = function() { imageElement.src = src; console.log(`WebP version not found for ${src}, using original.`); }; } // 并发加载图片 function loadImages(imageUrls) { return Promise.all(imageUrls.map(url => { return new Promise((resolve, reject) => { const img = new Image(); img.src = url; img.onload = resolve; img.onerror = reject; }); })); } // 使用IntersectionObserver动态加载图片 function setupDynamicLoading(images) { const viewportHeight = window.innerHeight; const rootMarginBottom = `${viewportHeight / 2}px`; // 设置rootMargin为视口高度的50% const observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; const src = img.getAttribute('data-src'); if (src) { supportsWebP((isSupported) => { if (isSupported) { replaceWithWebP(img, src); } else { img.src = src; } }); observer.unobserve(img); // 停止观察已加载的图片 } } }); }, { root: null, rootMargin: `0px 0px ${rootMarginBottom} 0px` }); // 只增加底部的rootMargin images.forEach(img => { if (!img.getAttribute('data-src')) { img.setAttribute('data-src', img.src); img.src = ''; // 清空src以防止立即加载 } observer.observe(img); }); } // 预加载首屏图片 function preloadFirstScreenImages(images) { const viewportHeight = window.innerHeight; const firstScreenImages = Array.from(images).filter(img => { const rect = img.getBoundingClientRect(); return rect.top <= viewportHeight && rect.bottom >= 0; }).map(img => img.getAttribute('data-src')); if (firstScreenImages.length > 0) { loadImages(firstScreenImages).then(() => { console.log('首屏图片已预加载'); }).catch(error => { console.error('首屏图片预加载失败:', error); }); } } // 确保DOM完全加载后再执行动态加载和首屏图片预加载 window.addEventListener('load', () => { const images = document.querySelectorAll('img'); preloadFirstScreenImages(images); // 首屏图片预加载 setupDynamicLoading(images); // 动态加载所有图片 }); // 监听DOM变化,确保动态加载的内容也能被优化 const mutationObserver = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { const images = node.querySelectorAll('img'); if (images.length > 0) { preloadFirstScreenImages(images); // 对新添加的图片进行首屏预加载 setupDynamicLoading(images); // 对新添加的图片进行动态加载 } } }); }); }); mutationObserver.observe(document.body, { childList: true, subtree: true }); })();