Greasy Fork

Greasy Fork is available in English.

Webp图片加载优化

Optimize image loading by adding lazy loading, WebP support, and concurrent requests.

当前为 2025-03-14 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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);
        }
    });

})();