Web Comprehensive Optimization Script(web综合优化脚本)

Optimize rendering, event handling, resource loading, and more.

// ==UserScript==
// @name         Web Comprehensive Optimization Script(web综合优化脚本)
// @namespace    http://tampermonkey.net/
// @version      2.5
// @description  Optimize rendering, event handling, resource loading, and more.
// @author       KiwiFruit
// @match        *://*/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    // ========================
    // 配置中心
    // ========================
    const config = {
        debug: false, // 开启调试日志
        throttleDelay: 200, // 节流延迟
        debounceDelay: 300, // 防抖延迟
        retryAttempts: 3, // 资源加载最大重试次数
        retryDelay: 1000, // 重试间隔
        criticalCssPaths: { // 关键CSS路径映射
            'example.com': '/styles/example-critical.css',
            'anotherwebsite.com': '/styles/anotherwebsite-critical.css',
            default: '/styles/default-critical.css'
        },
        lazyCssSelector: '.lazy-css', // 非首屏CSS占位选择器
        rootMarginFactor: 0.1, // IntersectionObserver根边距系数
        enableWebWorker: true // 是否启用Web Worker(示例开关)
    };

    // ========================
    // 日志系统(支持分级)
    // ========================
    const logger = {
        debug: (msg) => {
            if (config.debug) console.log(`[DEBUG] ${msg}`);
        },
        warn: (msg) => console.warn(`[WARN] ${msg}`),
        error: (msg) => console.error(`[ERROR] ${msg}`)
    };

    // ========================
    // 工具函数
    // ========================
    const throttle = (func, delay) => {
        let lastCall = 0;
        return function (...args) {
            const now = Date.now();
            if (now - lastCall >= delay) {
                lastCall = now;
                func.apply(this, args);
            }
        };
    };

    const debounce = (func, delay) => {
        let timer;
        return function (...args) {
            clearTimeout(timer);
            timer = setTimeout(() => func.apply(this, args), delay);
        };
    };

    const calculateRootMargin = () => {
        const windowHeight = window.innerHeight;
        const marginBottom = Math.max(0, windowHeight * config.rootMarginFactor);
        return `0px 0px ${marginBottom}px 0px`;
    };

    // ========================
    // 资源加载器(带重试)
    // ========================
    class ResourceLoader {
        static loadResource(url, type) {
            return new Promise((resolve, reject) => {
                const element = document.createElement(type === 'script' ? 'script' : 'link');
                if (type === 'script') {
                    element.src = url;
                } else {
                    element.rel = 'stylesheet';
                    element.href = url;
                }
                element.onload = resolve;
                element.onerror = () => reject(new Error(`${type} loading failed: ${url}`));
                document.head.appendChild(element);
            });
        }

        static async loadWithRetry(loaderFn, maxRetries = config.retryAttempts, delay = config.retryDelay) {
            for (let i = 0; i < maxRetries; i++) {
                try {
                    return await loaderFn();
                } catch (error) {
                    if (i === maxRetries - 1) {
                        logger.error(`Resource load failed after ${maxRetries} attempts: ${error.message}`);
                        throw error;
                    }
                    logger.warn(`Retrying in ${delay / 1000}s...`);
                    await new Promise(resolve => setTimeout(resolve, delay));
                }
            }
        }

        static async loadStylesheet(href) {
            await this.loadWithRetry(() => this.loadResource(href, 'stylesheet'));
            logger.debug(`Stylesheet loaded: ${href}`);
        }

        static async loadScript(src) {
            await this.loadWithRetry(() => this.loadResource(src, 'script'));
            logger.debug(`Script loaded: ${src}`);
        }
    }

    // ========================
    // 核心性能指标监控
    // ========================
    class PerformanceMonitor {
        static init() {
            // FCP(首次内容绘制)
            new PerformanceObserver((entryList) => {
                const entries = entryList.getEntries();
                logger.debug(`FCP: ${entries[0].startTime}ms`);
            }).observe({ type: 'paint', buffered: true });

            // LCP(最大内容绘制)
            new PerformanceObserver((entryList, observer) => {
                const entries = entryList.getEntries();
                const lastEntry = entries[entries.length - 1];
                logger.debug(`LCP: ${lastEntry.startTime}ms`);
                observer.disconnect();
            }).observe({ type: 'largest-contentful-paint', buffered: true });

            // CLS(累积布局偏移)
            new PerformanceObserver((entryList) => {
                const entries = entryList.getEntries();
                let totalCLS = 0;
                entries.forEach(entry => {
                    if (!entry.hadRecentInput) {
                        totalCLS += entry.value;
                    }
                });
                logger.debug(`CLS: ${totalCLS.toFixed(3)}`);
            }).observe({ type: 'layout-shift', buffered: true });
        }
    }

    // ========================
    // 硬件加速优化
    // ========================
    class HardwareAcceleration {
        static init() {
            const className = 'enable-hardware-acceleration';
            const styleSheet = `
                .${className} {
                    transform: translateZ(0) !important;
                    will-change: transform !important;
                }
            `;
            const styleElement = document.createElement('style');
            styleElement.type = 'text/css';
            styleElement.appendChild(document.createTextNode(styleSheet));
            document.head.appendChild(styleElement);

            const observer = new IntersectionObserver((entries) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        entry.target.classList.add(className);
                    } else {
                        entry.target.classList.remove(className);
                    }
                });
            }, { rootMargin: calculateRootMargin(), threshold: 0 });

            return observer;
        }
    }

    // ========================
    // 非首屏CSS懒加载(兼容回退)
    // ========================
    class LazyCssLoader {
        static init() {
            if (!window.IntersectionObserver) {
                this.fallback();
                return;
            }

            const observer = new IntersectionObserver((entries, io) => {
                entries.forEach(entry => {
                    if (entry.isIntersecting) {
                        const element = entry.target;
                        const href = element.getAttribute('data-lazy-css');
                        if (href) {
                            ResourceLoader.loadStylesheet(href).then(() => {
                                if (element.parentElement) {
                                    element.parentElement.removeChild(element);
                                }
                            });
                        }
                        io.unobserve(element);
                    }
                });
            }, { rootMargin: calculateRootMargin(), threshold: 0 });

            document.querySelectorAll(config.lazyCssSelector).forEach(el => observer.observe(el));
        }

        static fallback() {
            logger.warn('IntersectionObserver not supported, falling back to polling...');
            const checkVisible = () => {
                document.querySelectorAll(config.lazyCssSelector).forEach(element => {
                    const rect = element.getBoundingClientRect();
                    if (rect.top < window.innerHeight && rect.bottom > 0) {
                        const href = element.getAttribute('data-lazy-css');
                        ResourceLoader.loadStylesheet(href).then(() => {
                            if (element.parentElement) {
                                element.parentElement.removeChild(element);
                            }
                        });
                    }
                });
            };

            setInterval(checkVisible, 500);
        }
    }

    // ========================
    // Web Worker(示例)
    // ========================
    class WorkerManager {
        static init() {
            if (!config.enableWebWorker || !window.Worker) {
                logger.warn('Web Worker not available or disabled.');
                return;
            }

            const workerCode = `
                self.onmessage = function(e) {
                    const result = heavyProcessing(e.data);
                    self.postMessage(result);
                };

                function heavyProcessing(data) {
                    let sum = 0;
                    for (let i = 0; i < data; i++) {
                        sum += Math.sqrt(i);
                    }
                    return sum;
                }
            `;

            const blob = new Blob([workerCode], { type: 'application/javascript' });
            const url = URL.createObjectURL(blob);
            const worker = new Worker(url);

            worker.onmessage = function(e) {
                logger.debug('Worker result:', e.data);
            };

            worker.postMessage(1000000); // 示例任务
        }
    }

    // ========================
    // 事件绑定(节流/防抖)
    // ========================
    class EventManager {
        static init() {
            window.addEventListener('scroll', throttle(() => {
                logger.debug('Scroll event triggered (throttled)');
            }, config.throttleDelay));

            window.addEventListener('resize', debounce(() => {
                logger.debug('Resize event triggered (debounced)');
            }, config.debounceDelay));
        }
    }

    // ========================
    // DOM变化监听
    // ========================
    class DomMonitor {
        static init() {
            const observer = new MutationObserver(throttle(mutations => {
                mutations.forEach(mutation => {
                    mutation.addedNodes.forEach(node => {
                        if (node.nodeType === 1 && node.matches(config.lazyCssSelector)) {
                            LazyCssLoader.init();
                        }
                    });
                });
            }, 100));

            observer.observe(document.body, { childList: true, subtree: true });
        }
    }

    // ========================
    // 初始化流程
    // ========================
    class App {
        static async init() {
            // 性能监控
            PerformanceMonitor.init();

            // 关键CSS预加载
            const hostname = window.location.hostname;
            let criticalCssUrl;
            if (hostname.includes('example.com')) {
                criticalCssUrl = config.criticalCssPaths['example.com'];
            } else if (hostname.includes('anotherwebsite.com')) {
                criticalCssUrl = config.criticalCssPaths['anotherwebsite.com'];
            } else {
                criticalCssUrl = config.criticalCssPaths.default;
            }

            if (criticalCssUrl) {
                try {
                    await ResourceLoader.loadStylesheet(`${window.location.origin}${criticalCssUrl}`);
                } catch (error) {
                    logger.error(`Failed to load critical CSS: ${error.message}`);
                }
            }

            // 初始化各模块
            HardwareAcceleration.init();
            LazyCssLoader.init();
            DomMonitor.init();
            EventManager.init();
            WorkerManager.init();
        }
    }

    // ========================
    // 页面生命周期管理
    // ========================
    document.addEventListener("DOMContentLoaded", () => {
        App.init().catch(error => logger.error(`Initialization failed: ${error.message}`));
    });

    window.addEventListener("beforeunload", () => {
        // 清理资源(如MutationObserver)
        logger.debug('Page is unloading...');
    });

})();