// ==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 // @downloadURL none // ==/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); } }); })();