Web性能综合优化工具箱

web浏览提速80%

// ==UserScript==
// @name         Web性能综合优化工具箱
// @namespace    http://tampermonkey.net/
// @version      3.2.2
// @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 || '')
    };
    /**
     * 配置中心(可控的状态管理)
     */
    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) {
                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')));
                }
            }
        },
        safeGetData: (el, name, defaultValue) => {
            try {
                const value = el.dataset[name];
                if (!value) return defaultValue;
                if (value.match(/^[{[]/)) return JSON.parse(value);
                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. 基础类(抽象公共逻辑)
    // ========================
    /**
     * 模块基类(统一生命周期管理)
     */
    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公共逻辑)
     */
    class BaseObserver extends BaseModule {
        constructor(moduleName, configKey) {
            super(moduleName);
            this.observer = null;
            this.configKey = configKey;
            this.observers = [];
        }
        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. 功能模块(基于基类实现)
    // ========================
    /**
     * 智能懒加载模块
     */
    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);
                }
            });
        }
        useObserverLazyLoad() {
            Logger.info(this.moduleName, '使用Observer懒加载方案');
            this.createObserver(
                () => {},
                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 });
        }
        markLoaded(el) {
            el.classList.add('loaded', 'lazy-loaded');
            el.classList.remove('load-failed');
            Logger.debug(this.moduleName, `加载成功: ${el.src || el.href}`);
        }
        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;
        }
        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();
        }
        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));
        }
        collectCriticalCSSUrls() {
            const urls = new Set();
            Config.get('criticalCSS.selectors').forEach(selector => {
                document.querySelectorAll(selector).forEach(el => {
                    const url = Utils.safeGetData(el, 'href', '');
                    if (url) {
                        urls.add(url);
                        el.remove();
                    }
                });
            });
            const meta = document.querySelector('meta[name="critical-css"]');
            if (meta) meta.content.split(',').forEach(url => url && urls.add(url.trim()));
            return Array.from(urls);
        }
        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');
            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 });
        }
        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 && this.lazyLoader.initialized && Config.get('lazyLoad.enabled')) {
                this.lazyLoader.observeElements(Config.get('lazyLoad.selector'));
            }
            if (this.gpuAccelerator && this.gpuAccelerator.initialized && 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 = {}; // 延迟初始化模块容器
        }
        // 分步初始化模块,增加容错检查
        init() {
            super.init();
            try {
                // 1. 关键CSS加载器(最高优先级)
                this.modules.criticalCSSLoader = new CriticalCSSLoader();
                this.modules.criticalCSSLoader.init();

                // 2. 懒加载器(核心模块,失败时记录并继续)
                try {
                    this.modules.lazyLoader = new LazyLoader();
                    this.modules.lazyLoader.init();
                } catch (e) {
                    Logger.error('AppController', 'LazyLoader初始化失败,将跳过该模块', e);
                    this.modules.lazyLoader = null; // 标记为null,避免后续引用错误
                }

                // 3. 事件优化器
                this.modules.eventOptimizer = new EventOptimizer();
                this.modules.eventOptimizer.init();

                // 4. 硬件加速器
                try {
                    this.modules.gpuAccelerator = new GpuAccelerator();
                    this.modules.gpuAccelerator.init();
                } catch (e) {
                    Logger.error('AppController', 'GpuAccelerator初始化失败,将跳过该模块', e);
                    this.modules.gpuAccelerator = null;
                }

                // 5. DOM观察者(依赖懒加载和硬件加速模块,需判断是否存在)
                this.modules.domObserver = new DomObserver(
                    this.modules.lazyLoader,
                    this.modules.gpuAccelerator
                );
                this.modules.domObserver.init();

                // 页面卸载清理
                window.addEventListener('beforeunload', () => this.destroy());

                // SPA路由切换支持
                window.addEventListener('spa:navigate', () => {
                    this.destroy();
                    this.init();
                });

            } catch (error) {
                Logger.error('AppController', '初始化过程发生致命错误', error);
                this.destroy(); // 尝试清理已初始化的模块
            }
        }
        // 按相反顺序销毁模块
        destroy() {
            Object.values(this.modules).reverse().forEach(module => {
                if (module && typeof module.destroy === 'function') {
                    try {
                        module.destroy();
                    } catch (e) {
                        Logger.error('AppController', `模块${module.moduleName}销毁失败`, e);
                    }
                }
            });
            super.destroy();
        }
    }
    // ========================
    // 启动应用(增加启动容错)
    // ========================
    function bootstrap() {
        try {
            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;
            }
        } catch (error) {
            console.error('[PerfOpt] 应用启动失败', error);
        }
    }
    // 对外API
    window.PerfUtils = {
        getConfig: Config.getAll,
        setConfig: Config.set,
        throttle: Utils.throttle,
        debounce: Utils.debounce,
        loadWithRetry: Utils.loadWithRetry
    };
    bootstrap();
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址