Greasy Fork

Greasy Fork is available in English.

Web性能综合优化工具箱

web浏览提速80%

当前为 2025-08-20 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Web性能综合优化工具箱
// @namespace    http://tampermonkey.net/
// @version      3.2.1
// @description  web浏览提速80%
// @author       KiwiFruit
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

/**
 * 生产级Web性能优化核心工具
 * 设计理念:
 * - 基于基类抽象减少重复代码
 * - 显式依赖管理与生命周期控制
 * - 分层错误处理(日志+UI反馈+事件通知)
 * - 简化逻辑分支,提升可读性
 */
(function () {
    'use strict';

    // ========================
    // 1. 基础工具与环境检测
    // ========================

    /**
     * 环境检测工具(集中管理环境判断,避免重复计算)
     * 作用:预计算浏览器特性、设备性能等环境信息,供各模块直接使用
     */
    const Environment = {
        // 浏览器特性支持
        features: {
            nativeLazyLoad: 'loading' in HTMLImageElement.prototype,
            intersectionObserver: 'IntersectionObserver' in window,
            webWorker: 'Worker' in window,
            performanceObserver: 'PerformanceObserver' in window
        },
        // 设备性能等级(0-2:低-高)
        performanceTier: (() => {
            if (navigator.hardwareConcurrency >= 4) return 2;
            if (window.devicePixelRatio <= 1.5) return 1;
            return 0;
        })(),
        // 网络类型
        networkType: navigator.connection?.effectiveType || 'unknown',

        // 工具方法:判断是否为低性能环境
        isLowPerformance() {
            return this.performanceTier === 0 || this.networkType === '2g';
        }
    };

    /**
     * 日志系统(分级+上下文信息)
     * 改进:添加模块名前缀,便于定位日志来源
     */
    const Logger = {
        debug: (module, msg) => {
            if (Config.get('debug')) console.log(`[PerfOpt][${module}] DEBUG: ${msg}`);
        },
        info: (module, msg) => console.info(`[PerfOpt][${module}] INFO: ${msg}`),
        warn: (module, msg) => console.warn(`[PerfOpt][${module}] WARN: ${msg}`),
        error: (module, msg, error) => console.error(`[PerfOpt][${module}] ERROR: ${msg}`, error || '')
    };

    /**
     * 配置中心(可控的状态管理)
     * 改进:通过get/set方法封装配置,记录变更日志,避免直接修改
     */
    const Config = (() => {
        const config = {
            debug: false,
            throttleDelay: 200,
            debounceDelay: 300,
            retryAttempts: 3,
            retryDelay: 1000,
            lazyLoad: { enabled: true, selector: '.js-lazy-load', rootMargin: '100px 0px', preferNative: true },
            criticalCSS: { enabled: true, selectors: ['.js-critical-css'], preloadTimeout: 5000 },
            hardwareAcceleration: { enabled: true, selector: '.js-animate, .js-transform' },
            webWorker: { enabled: true, customTask: null },
            performanceMonitor: { enabled: false, metrics: ['fcp', 'lcp', 'cls'] }
        };

        return {
            get(key) {
                // 支持嵌套获取(如get('lazyLoad.enabled'))
                const keys = key.split('.');
                return keys.reduce((obj, k) => obj?.[k], config);
            },
            set(key, value) {
                const keys = key.split('.');
                const lastKey = keys.pop();
                const target = keys.reduce((obj, k) => obj?.[k], config);
                if (target && typeof target[lastKey] !== 'undefined') {
                    const oldValue = target[lastKey];
                    target[lastKey] = value;
                    Logger.info('Config', `更新配置: ${key}=${value}(旧值: ${oldValue})`);
                    return true;
                }
                Logger.error('Config', `配置键不存在: ${key}`);
                return false;
            },
            getAll() { return { ...config }; }
        };
    })();

    /**
     * 通用工具函数(减少重复,提升复用)
     */
    const Utils = {
        // 节流与防抖(基础工具)
        throttle: (func, delay) => {
            let lastCall = 0;
            return function (...args) {
                const now = Date.now();
                if (now - lastCall >= delay) {
                    lastCall = now;
                    func.apply(this, args);
                }
            };
        },
        debounce: (func, delay) => {
            let timer;
            return function (...args) {
                clearTimeout(timer);
                timer = setTimeout(() => func.apply(this, args), delay);
            };
        },

        // 带重试的加载(统一错误重试逻辑)
        loadWithRetry: async (loaderFn, moduleName) => {
            for (let i = 0; i < Config.get('retryAttempts'); i++) {
                try {
                    return await loaderFn();
                } catch (error) {
                    const isLastAttempt = i === Config.get('retryAttempts') - 1;
                    if (isLastAttempt) {
                        Logger.error(moduleName, `加载失败(已达最大重试次数)`, error);
                        throw error; // 抛出供上层处理
                    }
                    Logger.warn(moduleName, `加载失败,${Config.get('retryDelay')}ms后重试(${i+1}/${Config.get('retryAttempts')})`);
                    await new Promise(resolve => setTimeout(resolve, Config.get('retryDelay')));
                }
            }
        },

        // 安全解析data属性
        safeGetData: (el, name, defaultValue) => {
            try {
                const value = el.dataset[name];
                if (!value) return defaultValue;
                if (value.match(/^[{[]/)) return JSON.parse(value); // 解析JSON
                if (value.toLowerCase() === 'true') return true;
                if (value.toLowerCase() === 'false') return false;
                const num = Number(value);
                return !isNaN(num) ? num : value;
            } catch (e) {
                Logger.warn('Utils', `解析data-${name}失败`, e);
                return defaultValue;
            }
        },

        // 类型检查
        is: {
            func: v => typeof v === 'function',
            elem: v => v instanceof Element,
            str: v => typeof v === 'string',
            num: v => typeof v === 'number' && !isNaN(v)
        }
    };

    // ========================
    // 2. 基础类(抽象公共逻辑)
    // ========================

    /**
     * 模块基类(统一生命周期管理)
     * 解决:各模块init/destroy逻辑重复问题
     */
    class BaseModule {
        constructor(moduleName) {
            this.moduleName = moduleName;
            this.initialized = false;
        }

        // 初始化入口(子类实现具体逻辑)
        init() {
            if (this.initialized) {
                Logger.warn(this.moduleName, '已初始化,避免重复调用');
                return;
            }
            this.initialized = true;
            Logger.info(this.moduleName, '初始化开始');
        }

        // 销毁入口(子类实现具体逻辑)
        destroy() {
            if (!this.initialized) return;
            this.initialized = false;
            Logger.info(this.moduleName, '销毁完成');
        }

        // 触发模块事件(统一事件机制)
        emitEvent(eventName, detail = {}) {
            window.dispatchEvent(new CustomEvent(`perfopt:${this.moduleName}:${eventName}`, {
                detail: { ...detail, module: this.moduleName, timestamp: Date.now() }
            }));
        }
    }

    /**
     * 观察者基类(封装IntersectionObserver公共逻辑)
     * 解决:LazyLoader、GpuAccelerator中观察者创建逻辑重复问题
     */
    class BaseObserver extends BaseModule {
        constructor(moduleName, configKey) {
            super(moduleName);
            this.observer = null; // 观察者实例
            this.configKey = configKey; // 配置键(如'lazyLoad')
            this.observers = []; // 存储所有观察者实例
        }

        // 创建观察者(子类实现handleIntersect回调)
        createObserver(handleIntersect, rootMargin = '0px') {
            if (!Environment.features.intersectionObserver) {
                Logger.warn(this.moduleName, '不支持IntersectionObserver,无法创建观察者');
                return null;
            }

            const observer = new IntersectionObserver((entries) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        this.handleIntersect(entry.target);
                    } else {
                        this.handleLeave(entry.target); // 可选:处理离开视口
                    }
                });
            }, { rootMargin, threshold: 0.01 });

            this.observers.push(observer);
            return observer;
        }

        // 观察元素(统一处理)
        observeElements(selector) {
            if (!selector || !this.observers.length) return;
            document.querySelectorAll(selector).forEach(el => {
                if (!el.dataset[this.moduleName + 'Observed']) {
                    this.observers[0].observe(el);
                    el.dataset[this.moduleName + 'Observed'] = 'true';
                }
            });
        }

        // 处理进入视口(子类必须实现)
        handleIntersect(target) { throw new Error('子类需实现handleIntersect方法'); }

        // 处理离开视口(可选实现)
        handleLeave(target) {}

        // 销毁所有观察者
        destroy() {
            super.destroy();
            this.observers.forEach(observer => observer.disconnect());
            this.observers = [];
        }
    }

    // ========================
    // 3. 功能模块(基于基类实现)
    // ========================

    /**
     * 智能懒加载模块(解决循环复杂度高、错误处理弱问题)
     * 改进:用策略模式拆分元素处理逻辑,减少if-else
     */
    class LazyLoader extends BaseObserver {
        constructor() {
            super('LazyLoader', 'lazyLoad');
            this.scrollHandler = null; // 降级方案的滚动处理器
            // 加载策略映射(按元素类型+资源类型)
            this.loadStrategies = {
                IMG: { src: (el, src) => el.src = src },
                SCRIPT: { src: (el, src) => { el.src = src; el.async = true; } },
                LINK: { href: (el, href) => el.href = href }
            };
        }

        init() {
            super.init();
            if (!Config.get('lazyLoad.enabled')) {
                Logger.info(this.moduleName, '已禁用');
                return;
            }

            // 根据环境选择加载方案
            if (Environment.features.nativeLazyLoad && Config.get('lazyLoad.preferNative')) {
                this.useNativeLazyLoad();
            } else if (Environment.features.intersectionObserver) {
                this.useObserverLazyLoad();
            } else {
                this.useFallbackLazyLoad();
            }
        }

        // 原生懒加载方案
        useNativeLazyLoad() {
            Logger.info(this.moduleName, '使用原生懒加载方案');
            document.querySelectorAll(Config.get('lazyLoad.selector')).forEach(el => {
                if (['IMG', 'IFRAME'].includes(el.tagName)) {
                    el.loading = 'lazy';
                    this.loadElement(el); // 加载资源
                } else {
                    this.loadNonMedia(el); // 非媒体元素用脚本加载
                }
            });
        }

        // Observer懒加载方案
        useObserverLazyLoad() {
            Logger.info(this.moduleName, '使用Observer懒加载方案');
            this.createObserver(
                () => {}, // handleIntersect由loadElement处理
                Config.get('lazyLoad.rootMargin')
            );
            this.observeElements(Config.get('lazyLoad.selector'));
        }

        // 降级方案(滚动监听)
        useFallbackLazyLoad() {
            Logger.warn(this.moduleName, '使用滚动监听降级方案');
            this.scrollHandler = Utils.throttle(() => {
                document.querySelectorAll(Config.get('lazyLoad.selector')).forEach(el => {
                    if (!el.classList.contains('loaded') && this.isInViewport(el)) {
                        this.loadElement(el);
                    }
                });
            }, Config.get('throttleDelay'));

            window.addEventListener('scroll', this.scrollHandler);
            this.scrollHandler(); // 初始检查
        }

        // 加载元素(策略模式)
        loadElement(el) {
            if (!Utils.is.elem(el) || el.classList.contains('loaded')) return;

            try {
                const src = Utils.safeGetData(el, 'src', '') || Utils.safeGetData(el, 'lazySrc', '');
                const href = Utils.safeGetData(el, 'href', '') || Utils.safeGetData(el, 'lazyHref', '');
                const strategy = this.loadStrategies[el.tagName]?.[src ? 'src' : 'href'];

                if (strategy && (src || href)) {
                    strategy(el, src || href); // 执行对应策略
                    this.bindLoadEvents(el, src || href); // 绑定加载事件
                } else {
                    Logger.warn(this.moduleName, `不支持的元素类型: ${el.tagName}`);
                    this.markFailed(el);
                }
            } catch (error) {
                Logger.error(this.moduleName, '加载元素失败', error);
                this.markFailed(el);
            }
        }

        // 处理非媒体元素(如脚本)
        loadNonMedia(el) {
            const src = Utils.safeGetData(el, 'src', '');
            if (el.tagName === 'SCRIPT' && src) {
                const script = document.createElement('script');
                script.src = src;
                script.async = true;
                script.onload = () => this.markLoaded(script);
                script.onerror = (e) => this.markFailed(script, e);
                el.parentNode.replaceChild(script, el);
            }
        }

        // 绑定加载成功/失败事件
        bindLoadEvents(el, url) {
            el.addEventListener('load', () => {
                this.markLoaded(el);
                this.emitEvent('loaded', { url, tag: el.tagName });
            }, { once: true });

            el.addEventListener('error', (e) => {
                this.markFailed(el, e);
                this.emitEvent('error', { url, tag: el.tagName, error: e });
            }, { once: true });
        }

        // 标记加载成功(UI反馈)
        markLoaded(el) {
            el.classList.add('loaded', 'lazy-loaded');
            el.classList.remove('load-failed');
            Logger.debug(this.moduleName, `加载成功: ${el.src || el.href}`);
        }

        // 标记加载失败(UI反馈)
        markFailed(el, error) {
            el.classList.add('load-failed');
            el.classList.remove('loaded', 'lazy-loaded');
            Logger.error(this.moduleName, `加载失败: ${el.src || el.href}`, error);
        }

        // 检查元素是否在视口(降级方案用)
        isInViewport(el) {
            const rect = el.getBoundingClientRect();
            return rect.top <= window.innerHeight + 100 && rect.left <= window.innerWidth;
        }

        // 处理进入视口(Observer方案)
        handleIntersect(target) {
            this.loadElement(target);
            this.observers.forEach(observer => observer.unobserve(target)); // 停止观察
        }

        // 销毁
        destroy() {
            super.destroy();
            if (this.scrollHandler) {
                window.removeEventListener('scroll', this.scrollHandler);
                this.scrollHandler = null;
            }
        }
    }

    /**
     * 首屏关键CSS预加载模块(解决错误处理弱、结构混乱问题)
     */
    class CriticalCSSLoader extends BaseModule {
        constructor() {
            super('CriticalCSSLoader');
            this.loadedUrls = new Set(); // 已加载的CSS URL
        }

        init() {
            super.init();
            if (!Config.get('criticalCSS.enabled')) {
                Logger.info(this.moduleName, '已禁用');
                return;
            }

            const cssUrls = this.collectCriticalCSSUrls();
            if (cssUrls.length === 0) {
                Logger.info(this.moduleName, '未发现关键CSS资源');
                return;
            }

            cssUrls.forEach(url => this.preloadCSS(url));
        }

        // 收集关键CSS URL(统一来源)
        collectCriticalCSSUrls() {
            const urls = new Set();
            // 1. 从配置选择器收集
            Config.get('criticalCSS.selectors').forEach(selector => {
                document.querySelectorAll(selector).forEach(el => {
                    const url = Utils.safeGetData(el, 'href', '');
                    if (url) {
                        urls.add(url);
                        el.remove(); // 移除原元素避免重复加载
                    }
                });
            });
            // 2. 从meta标签收集
            const meta = document.querySelector('meta[name="critical-css"]');
            if (meta) meta.content.split(',').forEach(url => url && urls.add(url.trim()));
            return Array.from(urls);
        }

        // 预加载CSS(带超时和降级)
        preloadCSS(url) {
            if (this.loadedUrls.has(url)) return;

            Logger.info(this.moduleName, `预加载关键CSS: ${url}`);
            const link = document.createElement('link');
            link.rel = 'preload';
            link.as = 'style';
            link.href = url;
            link.crossOrigin = 'anonymous';

            // 超时处理
            const timeoutId = setTimeout(() => {
                if (!this.loadedUrls.has(url)) {
                    Logger.error(this.moduleName, `预加载超时: ${url}`);
                    this.fallbackLoad(url); // 降级加载
                }
            }, Config.get('criticalCSS.preloadTimeout'));

            // 加载成功
            link.onload = () => {
                clearTimeout(timeoutId);
                link.rel = 'stylesheet';
                this.loadedUrls.add(url);
                this.emitEvent('loaded', { url });
                document.body.classList.add('critical-css-loaded');
                Logger.debug(this.moduleName, `预加载成功: ${url}`);
            };

            // 加载失败
            link.onerror = () => {
                clearTimeout(timeoutId);
                this.fallbackLoad(url);
            };

            document.head.appendChild(link);
        }

        // 降级加载(直接作为样式表)
        fallbackLoad(url) {
            if (this.loadedUrls.has(url)) return;

            Logger.warn(this.moduleName, `降级加载CSS: ${url}`);
            const link = document.createElement('link');
            link.rel = 'stylesheet';
            link.href = url;
            link.onload = () => {
                this.loadedUrls.add(url);
                this.emitEvent('fallback-loaded', { url });
            };
            link.onerror = (e) => this.emitEvent('error', { url, error: e });
            document.head.appendChild(link);
        }
    }

    /**
     * 事件优化模块(解决结构混乱、解耦问题)
     */
    class EventOptimizer extends BaseModule {
        constructor() {
            super('EventOptimizer');
            this.handlers = {
                scroll: Utils.throttle(() => this.emitEvent('scroll'), Config.get('throttleDelay')),
                resize: Utils.debounce(() => this.emitEvent('resize'), Config.get('debounceDelay'))
            };
        }

        init() {
            super.init();
            window.addEventListener('scroll', this.handlers.scroll);
            window.addEventListener('resize', this.handlers.resize);
        }

        destroy() {
            super.destroy();
            window.removeEventListener('scroll', this.handlers.scroll);
            window.removeEventListener('resize', this.handlers.resize);
        }
    }

    /**
     * 硬件加速模块(解决重复代码、环境适配问题)
     */
    class GpuAccelerator extends BaseObserver {
        constructor() {
            super('GpuAccelerator', 'hardwareAcceleration');
            this.styleEl = null; // 注入的样式元素
        }

        init() {
            super.init();
            if (!Config.get('hardwareAcceleration.enabled')) {
                Logger.info(this.moduleName, '已禁用');
                return;
            }

            // 低性能设备降低强度
            if (Environment.isLowPerformance()) {
                Logger.info(this.moduleName, '低性能设备,仅加速核心元素');
                Config.set('hardwareAcceleration.selector', '.js-animate');
            }

            this.injectStyles();
            this.createObserver(() => {}, '50px'); // 空回调,在handleIntersect处理
            this.observeElements(Config.get('hardwareAcceleration.selector'));
        }

        // 注入硬件加速样式
        injectStyles() {
            this.styleEl = document.createElement('style');
            this.styleEl.textContent = `
                .gpu-accelerate { transform: translate3d(0,0,0); will-change: transform; }
                .gpu-accelerate.inactive { will-change: auto; }
            `;
            document.head.appendChild(this.styleEl);
        }

        // 处理进入视口(启用加速)
        handleIntersect(target) {
            target.classList.add('gpu-accelerate');
            target.classList.remove('inactive');
        }

        // 处理离开视口(降低强度)
        handleLeave(target) {
            target.classList.add('inactive');
        }

        destroy() {
            super.destroy();
            if (this.styleEl) this.styleEl.remove();
        }
    }

    /**
     * DOM变化监听模块(解决耦合问题)
     */
    class DomObserver extends BaseModule {
        constructor(lazyLoader, gpuAccelerator) {
            super('DomObserver');
            this.lazyLoader = lazyLoader; // 依赖注入:仅依赖接口
            this.gpuAccelerator = gpuAccelerator;
            this.observer = null;
        }

        init() {
            super.init();
            this.observer = new MutationObserver(Utils.throttle((mutations) => {
                this.handleMutations(mutations);
            }, 200));
            this.observer.observe(document.body, { childList: true, subtree: true });
        }

        // 处理DOM变化
        handleMutations(mutations) {
            const addedEls = [];
            mutations.forEach(m => {
                m.addedNodes.forEach(node => {
                    if (node.nodeType === 1) { // 元素节点
                        addedEls.push(node);
                        addedEls.push(...node.querySelectorAll('*')); // 包含子元素
                    }
                });
            });

            // 通知其他模块处理新元素
            if (this.lazyLoader && Config.get('lazyLoad.enabled')) {
                this.lazyLoader.observeElements(Config.get('lazyLoad.selector'));
            }
            if (this.gpuAccelerator && Config.get('hardwareAcceleration.enabled')) {
                this.gpuAccelerator.observeElements(Config.get('hardwareAcceleration.selector'));
            }
        }

        destroy() {
            super.destroy();
            if (this.observer) this.observer.disconnect();
        }
    }

    // ========================
    // 4. 应用初始化(依赖管理)
    // ========================

    /**
     * 应用控制器(解决模块依赖与初始化顺序问题)
     */
    class AppController extends BaseModule {
        constructor() {
            super('AppController');
            // 创建模块实例(显式依赖)
            this.modules = {
                criticalCSSLoader: new CriticalCSSLoader(),
                lazyLoader: new LazyLoader(),
                eventOptimizer: new EventOptimizer(),
                gpuAccelerator: new GpuAccelerator(),
                domObserver: new DomObserver(
                    this.modules.lazyLoader,
                    this.modules.gpuAccelerator
                )
            };
        }

        // 按依赖顺序初始化
        init() {
            super.init();
            // 1. 关键CSS(优先级最高)
            this.modules.criticalCSSLoader.init();
            // 2. 懒加载与事件优化
            this.modules.lazyLoader.init();
            this.modules.eventOptimizer.init();
            // 3. 硬件加速
            this.modules.gpuAccelerator.init();
            // 4. DOM观察者(最后初始化,监听其他模块)
            this.modules.domObserver.init();

            // 页面卸载时清理
            window.addEventListener('beforeunload', () => this.destroy());
            // SPA路由切换支持
            window.addEventListener('spa:navigate', () => {
                this.destroy();
                this.init();
            });
        }

        // 按相反顺序销毁
        destroy() {
            Object.values(this.modules).reverse().forEach(module => module.destroy());
            super.destroy();
        }
    }

    // ========================
    // 启动应用
    // ========================
    function bootstrap() {
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', () => {
                const app = new AppController();
                app.init();
                window.PerfOptimizer = app; // 暴露全局控制接口
            });
        } else {
            const app = new AppController();
            app.init();
            window.PerfOptimizer = app;
        }
    }

    // 对外API(统一暴露)
    window.PerfUtils = {
        getConfig: Config.getAll,
        setConfig: Config.set,
        throttle: Utils.throttle,
        debounce: Utils.debounce,
        loadWithRetry: Utils.loadWithRetry
    };

    bootstrap();
})();