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