您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
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(); })();