// ==UserScript== // @name Ultimate Web Optimizer // @namespace https://greasyfork.org/zh-CN/users/1474228-moyu001 // @version 1.1 // @description 全面的网页性能优化方案(含懒加载/预加载/预连接/资源回收/中国平台优化) // @author moyu001 // @match *://*/* // @grant GM_getValue // @grant GM_setValue // @grant GM_log // @grant unsafeWindow // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; // ======================== // 配置中心 // ======================== const config = { debug: false, // 确保调试模式已开启 features: { lazyLoad: { enabled: true, minSize: 100, rootMargin: '200px', skipHidden: true }, preconnect: { enabled: true, whitelist: [ 'fonts.gstatic.com', 'cdnjs.cloudflare.com', 'unpkg.com', 'ajax.googleapis.com', 'maxcdn.bootstrapcdn.com', 'code.jquery.com', 'kit.fontawesome.com', 'fonts.googleapis.cn', 'fonts.loli.net', 'cdn.jsdelivr.net', 'cdn.bootcdn.net', 'cdn.bootcss.com', 'libs.baidu.com', 'cdn.staticfile.org', 'lf3-cdn-tos.bytecdntp.com', 'unpkg.zhimg.com', 'npm.elemecdn.com', // 中国CDN优化 'alicdn.com', 'bdstatic.com', 'sinaimg.cn', 'sogoucdn.com', 'bytedance.com', 'bytecdn.cn', 'pstatp.com', 'qpic.cn', 'hdslb.com', 'bilivideo.com', 'tencent-cloud.net', 'qcloud.com' ], maxConnections: 8 }, preload: { enabled: true, types: ['css', 'js', 'woff2'], maxPreloads: 6 }, layout: { stableImages: true, stableIframes: true, stableVideos: true }, captcha: { enabled: true, autoDetect: true, safeMode: true }, resourceRecycling: { enabled: true, memoryThreshold: 75, scrollRecycleMargin: 500, videoRecycleMargin: 1000, monitorInterval: 5000, maxBackgroundVideos: 2 }, videoRecycling: { enabled: true, protectPlaying: true, protectVisible: true, restoreOnScroll: true } }, networkAware: { enabled: true, connectionTypes: { 'slow-2g': { preload: false, lazyMargin: '500px' }, '2g': { preload: true, maxPreloads: 3 }, '3g': { preload: true, maxPreloads: 4 }, '4g': { preload: true, maxPreloads: 8 } } }, chinaPlatforms: { enabled: true, platforms: { taobao: ['taobao.com', 'tmall.com'], jd: ['jd.com'], douyin: ['douyin.com'], bilibili: ['bilibili.com'], baidu: ['baidu.com'], weibo: ['weibo.com'], tencent: ['qq.com'], pinduoduo: ['pinduoduo.com'], kuaishou: ['kuaishou.com'] } } }; // 公共API对象 - 用于暴露内部方法 const publicAPI = { triggerRecycling: null }; // 添加调试输出函数 const debugLog = (...args) => { if (config.debug) { console.log('[Optimizer]', ...args); } }; // 添加调试警告函数 const debugWarn = (...args) => { if (config.debug) { console.warn('[Optimizer]', ...args); } }; // ======================== // 控制台调试命令系统 // ======================== const initConsoleCommands = () => { // 确保只初始化一次 if (unsafeWindow.__optimizerCommands) { debugLog('控制台命令已初始化,跳过重复执行'); // 新增调试日志 return; } unsafeWindow.__optimizerCommands = true; // 修改:挂载到 unsafeWindow // 优化状态查看 unsafeWindow.optimizerStatus = () => { // 修改:挂载到 unsafeWindow const status = { lazyLoad: { enabled: config.features.lazyLoad.enabled, images: document.querySelectorAll('img[data-src]').length }, preconnect: { enabled: config.features.preconnect.enabled, connections: document.querySelectorAll('link[rel="preconnect"]').length }, preload: { enabled: config.features.preload.enabled, resources: document.querySelectorAll('link[rel="preload"]').length }, resourceRecycling: { enabled: config.features.resourceRecycling.enabled, recycled: document.querySelectorAll('img[data-src]:not([src]), video[data-recycled-state]').length }, chinaPlatform: isChinaPlatform() || '未检测到' }; console.groupCollapsed('[Optimizer] 当前状态'); console.table(status); console.groupEnd(); return status; }; // 中国平台检测 unsafeWindow.checkChinaPlatform = () => { const platform = isChinaPlatform(); if (platform) { console.log(`检测到中国平台: ${platform}`); } else { console.log('未检测到支持的中国平台'); } return platform; }; // 临时禁用优化器 unsafeWindow.disableOptimizer = () => { Object.keys(config.features).forEach(key => { config.features[key].enabled = false; }); console.warn('优化器已临时禁用,刷新页面后恢复'); }; // 强制资源回收 unsafeWindow.forceRecycle = () => { if (publicAPI.triggerRecycling) { publicAPI.triggerRecycling(); console.log('资源回收已手动触发'); } else { console.warn('资源回收功能未启用'); } }; console.log('优化器控制台命令已启用: optimizerStatus(), checkChinaPlatform(), disableOptimizer(), forceRecycle()'); debugLog('控制台命令初始化完成'); // 新增调试日志 }; // 在脚本加载后立即初始化控制台命令 initConsoleCommands(); // ======================== // 工具函数 // ======================== function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } function isElementInViewport(el, margin = 0) { if (!el) return false; const rect = el.getBoundingClientRect(); return ( rect.top <= (window.innerHeight + margin) && rect.left <= (window.innerWidth + margin) && rect.bottom >= -margin && rect.right >= -margin ); } const recyclingGuard = (() => { let lastRecycleTime = 0; const minRecycleInterval = 10000; return { canRecycle: () => { const now = Date.now(); if (now - lastRecycleTime > minRecycleInterval) { lastRecycleTime = now; return true; } return false; } }; })(); // ======================== // 中国平台检测与优化 // ======================== const isChinaPlatform = () => { const host = window.location.hostname; const platforms = config.chinaPlatforms.platforms; for (const platform in platforms) { if (platforms[platform].some(domain => host.includes(domain))) { debugLog(`检测到中国平台: ${platform}`); return platform; } } debugLog('未检测到中国平台'); return false; }; const applyChinaPlatformOptimizations = () => { if (!config.chinaPlatforms.enabled) { debugLog('中国平台优化已禁用'); return; } const platform = isChinaPlatform(); if (!platform) return; debugLog(`应用中国平台优化策略: ${platform}`); // 平台特定优化 switch(platform) { case 'taobao': config.features.lazyLoad.rootMargin = '500px'; document.querySelectorAll('.J_ImgSwitcher, .detail-img').forEach(img => { img.dataset.skipLazy = 'true'; }); debugLog('淘宝优化已应用'); break; case 'jd': config.features.preload.maxPreloads = 8; document.querySelectorAll('#preview img').forEach(img => { img.dataset.skipLazy = 'true'; }); debugLog('京东优化已应用'); break; case 'douyin': config.features.resourceRecycling.maxBackgroundVideos = 1; const douyinPlayer = document.querySelector('.xgplayer-container video'); if (douyinPlayer) douyinPlayer.dataset.protected = 'true'; debugLog('抖音优化已应用'); break; case 'bilibili': const bilibiliPlayer = document.querySelector('.bpx-player-video-wrap video'); if (bilibiliPlayer) bilibiliPlayer.dataset.protected = 'true'; // 弹幕优化 const danmuContainer = document.querySelector('.bpx-player-dm-wrap'); if (danmuContainer) danmuContainer.dataset.optimizeLayout = 'true'; debugLog('哔哩哔哩优化已应用'); break; case 'baidu': document.querySelectorAll('.c-img').forEach(img => { img.loading = 'eager'; }); debugLog('百度优化已应用'); break; case 'weibo': config.features.lazyLoad.rootMargin = '500px'; document.querySelectorAll('.avator, .avatar').forEach(img => { img.dataset.skipLazy = 'true'; }); debugLog('微博优化已应用'); break; case 'pinduoduo': config.features.resourceRecycling.memoryThreshold = 70; document.querySelectorAll('.goods-img').forEach(img => { img.dataset.skipLazy = 'true'; }); debugLog('拼多多优化已应用'); break; case 'kuaishou': config.features.resourceRecycling.videoRecycleMargin = 1000; const kuaishouPlayer = document.querySelector('.player-container video'); if (kuaishouPlayer) kuaishouPlayer.dataset.protected = 'true'; // 快手视频列表优化 const videoList = document.querySelector('.video-list'); if (videoList) { videoList.dataset.optimizeLayout = 'true'; } debugLog('快手优化已应用'); break; case 'tencent': // 腾讯视频优化 const tencentPlayer = document.querySelector('#txp_player video'); if (tencentPlayer) tencentPlayer.dataset.protected = 'true'; // 腾讯视频CDN预连接 config.features.preconnect.whitelist.push('qpic.cn', 'vpic.video.qq.com'); debugLog('腾讯优化已应用'); break; } // 通用中国平台优化 config.features.preconnect.maxConnections = 8; config.features.preload.maxPreloads = 6; config.features.resourceRecycling.memoryThreshold = 80; debugLog('通用中国平台优化已应用'); }; // ======================== // 核心优化模块 // ======================== // 图片懒加载系统 const initLazyLoad = () => { if (!config.features.lazyLoad.enabled) { debugLog('图片懒加载已禁用'); return; } debugLog('初始化图片懒加载系统'); const isLazyCandidate = (img) => { if (img.loading === 'eager') return false; if (img.complete) return false; if (img.src.startsWith('data:')) return false; if (img.classList.contains('captcha-image')) return false; if (img.dataset.skipLazy === 'true') return false; if (config.features.lazyLoad.skipHidden && window.getComputedStyle(img).display === 'none') return false; const rect = img.getBoundingClientRect(); return rect.width > config.features.lazyLoad.minSize && rect.height > config.features.lazyLoad.minSize; }; const processImage = (img) => { if (!img.dataset.src && img.src) { img.dataset.src = img.src; if (img.crossOrigin) { img.dataset.crossOrigin = img.crossOrigin; } img.removeAttribute('src'); } if (img.srcset && !img.dataset.srcset) { img.dataset.srcset = img.srcset; img.removeAttribute('srcset'); } return img; }; // 现代浏览器实现 if ('IntersectionObserver' in window) { debugLog('使用IntersectionObserver实现懒加载'); const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; if (img.dataset.src) { if (img.dataset.crossOrigin) { img.crossOrigin = img.dataset.crossOrigin; } img.src = img.dataset.src; debugLog(`懒加载图片: ${img.dataset.src}`); } if (img.dataset.srcset) { img.srcset = img.dataset.srcset; debugLog(`懒加载图片集: ${img.dataset.srcset}`); } observer.unobserve(img); } }); }, { rootMargin: config.features.lazyLoad.rootMargin, threshold: 0.01 }); // 初始图片 const images = document.querySelectorAll('img'); debugLog(`发现${images.length}张图片,正在筛选懒加载候选`); let lazyCount = 0; images.forEach(img => { if (isLazyCandidate(img)) { observer.observe(processImage(img)); lazyCount++; } }); debugLog(`已启用${lazyCount}张图片的懒加载`); // 动态加载监听 const mutationObserver = new MutationObserver(mutations => { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeName === 'IMG' && isLazyCandidate(node)) { observer.observe(processImage(node)); debugLog('动态添加的图片已启用懒加载'); } }); }); }); mutationObserver.observe(document.body, { childList: true, subtree: true }); debugLog('已启动动态图片监听'); // 清理钩子 window.addEventListener('beforeunload', () => { observer.disconnect(); mutationObserver.disconnect(); debugLog('懒加载系统已清理'); }); } else { debugLog('使用兼容模式实现懒加载'); // 兼容模式实现 const checkVisible = throttle(() => { document.querySelectorAll('img').forEach(img => { if (isLazyCandidate(img) && !img.src) { const rect = img.getBoundingClientRect(); if (rect.top < window.innerHeight + parseInt(config.features.lazyLoad.rootMargin)) { if (img.dataset.src) { if (img.dataset.crossOrigin) { img.crossOrigin = img.dataset.crossOrigin; } img.src = img.dataset.src; debugLog(`兼容模式加载图片: ${img.dataset.src}`); } if (img.dataset.srcset) { img.srcset = img.dataset.srcset; debugLog(`兼容模式加载图片集: ${img.dataset.srcset}`); } } } }); }, 200); // 添加动态图片监听 const mutationObserver = new MutationObserver(() => checkVisible()); mutationObserver.observe(document.body, { childList: true, subtree: true }); window.addEventListener('scroll', checkVisible); window.addEventListener('resize', checkVisible); checkVisible(); debugLog('兼容模式懒加载已启动'); } }; // 智能预连接系统 const initSmartPreconnect = () => { if (!config.features.preconnect.enabled) { debugLog('预连接系统已禁用'); return; } debugLog('初始化智能预连接系统'); const processed = new Set(); const whitelist = config.features.preconnect.whitelist; const doPreconnect = (hostname) => { if (processed.size >= config.features.preconnect.maxConnections) { debugWarn(`已达到最大预连接数 (${config.features.preconnect.maxConnections})`); return; } if (processed.has(hostname)) { debugLog(`已存在预连接: ${hostname}`); return; } const link = document.createElement('link'); link.rel = 'preconnect'; link.href = `//${hostname}`; document.head.appendChild(link); processed.add(hostname); debugLog(`已创建预连接: ${hostname}`); }; const scanResources = () => { debugLog('扫描资源进行预连接'); const resources = [ ...document.querySelectorAll('script[src], link[href], img[src]') ]; let found = 0; resources.forEach(el => { try { const url = new URL(el.src || el.href, window.location.href); const hostname = url.hostname; const matched = whitelist.find(domain => hostname.endsWith(domain) ); if (matched) { found++; doPreconnect(hostname); } } catch (e) { debugWarn('资源URL解析失败', e); } }); debugLog(`扫描完成,发现${found}个可预连接资源`); }; // 三级触发机制 scanResources(); setTimeout(scanResources, 2000); const mutationObserver = new MutationObserver(() => { setTimeout(scanResources, 100); }); mutationObserver.observe(document.body, { childList: true, subtree: true }); debugLog('已启动资源变化监听'); }; // 资源预加载系统 const initResourcePreload = () => { if (!config.features.preload.enabled) { debugLog('资源预加载已禁用'); return; } debugLog('初始化资源预加载系统'); const processed = new Set(); const types = config.features.preload.types; const max = config.features.preload.maxPreloads; const shouldPreload = (url) => { const ext = url.split('.').pop().toLowerCase(); return types.includes(ext); }; const doPreload = (url, asType) => { if (processed.size >= max) { debugWarn(`已达到最大预加载数 (${max})`); return; } if (processed.has(url)) { debugLog(`资源已预加载: ${url}`); return; } const link = document.createElement('link'); link.rel = 'preload'; link.as = asType; link.href = url; // 跨域资源处理 try { const parsedUrl = new URL(url, window.location.href); if (parsedUrl.origin !== window.location.origin) { if (asType === 'font') { link.setAttribute('crossorigin', 'anonymous'); } else if (asType === 'script' || asType === 'style') { link.crossOrigin = 'anonymous'; } debugLog(`跨域资源处理: ${url}`); } } catch (e) { debugWarn('URL解析失败', e); } document.head.appendChild(link); processed.add(url); debugLog(`已预加载资源: ${url} (类型: ${asType})`); }; const processFont = (cssUrl, fontUrl) => { try { const absoluteUrl = new URL(fontUrl, cssUrl).href; if (fontUrl.startsWith('data:')) return; if (shouldPreload(absoluteUrl)) { doPreload(absoluteUrl, 'font'); } } catch (e) { debugWarn(`字体解析失败: ${fontUrl}`, e); } }; const scanResources = () => { debugLog('扫描资源进行预加载'); let preloadCount = 0; // 处理CSS document.querySelectorAll('link[rel="stylesheet"]').forEach(link => { const cssUrl = link.href; if (cssUrl && shouldPreload(cssUrl)) { preloadCount++; doPreload(cssUrl, 'style'); // 解析CSS中的字体 if (types.includes('woff2')) { fetch(cssUrl, { mode: 'cors' }) .then(res => res.text()) .then(text => { const fontUrls = text.match(/url$["']?([^)"']+\.woff2?)["']?$/gi) || []; debugLog(`在CSS中发现${fontUrls.length}个字体资源`); fontUrls.forEach(fullUrl => { const cleanUrl = fullUrl.replace(/url$["']?|["']?$/g, ''); processFont(cssUrl, cleanUrl); }); }) .catch(e => { debugWarn(`CSS获取失败: ${cssUrl}`, e); }); } } }); // 处理JS document.querySelectorAll('script[src]').forEach(script => { const src = script.src; if (src && shouldPreload(src)) { preloadCount++; doPreload(src, 'script'); } }); debugLog(`扫描完成,预加载了${preloadCount}个资源`); }; scanResources(); const mutationObserver = new MutationObserver(() => { setTimeout(scanResources, 100); }); mutationObserver.observe(document.body, { childList: true, subtree: true }); debugLog('已启动资源变化监听'); }; // 布局稳定性优化 const initLayoutStabilization = () => { debugLog('初始化布局稳定性优化'); const styles = []; if (config.features.layout.stableImages) { styles.push(` img:not([width]):not([height]) { min-height: 1px; } @supports (aspect-ratio: 1/1) { img:not([width]):not([height]) { aspect-ratio: attr(width) / attr(height); } } `); debugLog('已添加图片布局稳定性规则'); } if (config.features.layout.stableIframes) { styles.push(` iframe:not([width]):not([height]) { width: 100%; height: auto; aspect-ratio: 16/9; } `); debugLog('已添加iframe布局稳定性规则'); } if (config.features.layout.stableVideos) { styles.push(` video:not([width]):not([height]) { max-width: 100%; aspect-ratio: 16/9; } `); debugLog('已添加视频布局稳定性规则'); } if (styles.length) { const style = document.createElement('style'); style.textContent = styles.join('\n'); document.head.appendChild(style); debugLog('布局稳定性样式已注入'); } else { debugLog('未添加任何布局稳定性规则'); } }; // CAPTCHA 保护系统 const initCaptchaProtection = () => { if (!config.features.captcha.enabled) { debugLog('验证码保护系统已禁用'); return; } debugLog('初始化验证码保护系统'); // 常见验证码特征库 const CAPTCHA_FINGERPRINTS = [ /recaptcha\/api\.js/i, /recaptcha\/enterprise\.js/i, /gstatic\.com\/recaptcha/, /recaptcha\/anchor\?/, /hcaptcha\.com\/1\/api\.js/, /hcaptcha\.com\/challenge\.css/, /challenges\.cloudflare\.com\/turnstile/, /challenges\.cloudflare\.com\/style/, /\/captcha\.(js|css)/i, /verify\.(png|jpg|gif)\?/i ]; // 检测当前页面是否有验证码 const hasCaptcha = () => { const htmlContent = document.documentElement.innerHTML; const scripts = Array.from(document.scripts); const found = CAPTCHA_FINGERPRINTS.some(pattern => htmlContent.match(pattern) || scripts.some(script => script.src && script.src.match(pattern)) ); if (found) { debugLog('检测到验证码系统'); } else { debugLog('未检测到验证码系统'); } return found; }; // 暂停可能干扰验证码的功能 const disableRiskyFeatures = () => { if (config.features.captcha.safeMode) { const originalLazyLoad = config.features.lazyLoad.enabled; const originalPreload = config.features.preload.enabled; config.features.lazyLoad.enabled = false; config.features.preload.enabled = false; debugWarn('验证码保护模式激活,已禁用懒加载和预加载'); // 恢复原始状态(在页面卸载时) window.addEventListener('beforeunload', () => { config.features.lazyLoad.enabled = originalLazyLoad; config.features.preload.enabled = originalPreload; debugLog('验证码保护模式已解除'); }); } }; // 恢复验证码 iframe 的默认样式 const restoreCaptchaFrames = () => { const frames = document.querySelectorAll('iframe'); let restoredCount = 0; frames.forEach(frame => { if (frame.src && CAPTCHA_FINGERPRINTS.some(p => frame.src.match(p))) { frame.style.aspectRatio = ''; frame.style.minHeight = ''; frame.classList.add('captcha-protected'); restoredCount++; } }); if (restoredCount > 0) { debugLog(`已恢复${restoredCount}个验证码框架的默认样式`); } }; if (hasCaptcha()) { disableRiskyFeatures(); restoreCaptchaFrames(); } }; // 资源回收系统 const initResourceRecycling = () => { if (!config.features.resourceRecycling.enabled) return; debugLog('初始化资源回收系统'); let memoryMonitor; const resourceMap = new WeakMap(); const recycleThreshold = config.features.resourceRecycling.memoryThreshold; // 视频资源回收策略 const videoRecycling = { recycle: (video) => { video.dataset.recycledState = JSON.stringify({ currentTime: video.currentTime, volume: video.volume, playbackRate: video.playbackRate, paused: video.paused, crossOrigin: video.crossOrigin, credentials: video.getAttribute('crossorigin') }); video.pause(); video.removeAttribute('src'); video.load(); debugLog(`视频资源已卸载: ${video.id || video.dataset.src || '匿名视频'}`); }, condition: (video) => { if (video.dataset.protected === 'true') { debugLog(`视频受保护,跳过回收: ${video.id || video.dataset.src || '匿名视频'}`); return false; } if (config.features.videoRecycling.protectPlaying && !video.paused) { debugLog(`视频正在播放,跳过回收: ${video.id || video.dataset.src || '匿名视频'}`); return false; } if (video.webkitDisplayingFullscreen || video === document.pictureInPictureElement) { debugLog(`视频全屏/PiP模式,跳过回收: ${video.id || video.dataset.src || '匿名视频'}`); return false; } if (video.dataset.userActivated === 'true') { debugLog(`视频用户激活,跳过回收: ${video.id || video.dataset.src || '匿名视频'}`); return false; } const inViewport = isElementInViewport(video, config.features.resourceRecycling.videoRecycleMargin); if (inViewport) { debugLog(`视频在可视区域内,跳过回收: ${video.id || video.dataset.src || '匿名视频'}`); return false; } debugLog(`视频符合回收条件: ${video.id || video.dataset.src || '匿名视频'}`); return true; }, restore: (video) => { if (video.dataset.src) { video.src = video.dataset.src; video.load(); if (video.dataset.recycledState) { const state = JSON.parse(video.dataset.recycledState); video.currentTime = state.currentTime; video.volume = state.volume; video.playbackRate = state.playbackRate; if (state.crossOrigin) { video.crossOrigin = state.crossOrigin; } if (state.credentials) { video.setAttribute('crossorigin', state.credentials); } if (!state.paused) { video.play().catch(e => { debugWarn(`视频自动播放失败: ${e.message}`); }); } } delete video.dataset.recycledState; debugLog(`视频资源已恢复: ${video.id || video.src || '匿名视频'}`); } } }; // 图片资源回收策略 const imageRecycling = { recycle: (img) => { if (img.dataset.src && img.src) { img.removeAttribute('src'); if (img.dataset.srcset) { img.removeAttribute('srcset'); } debugLog(`图片资源已卸载: ${img.dataset.src}`); } }, condition: (img) => { if (img.classList.contains('captcha-image') || img.closest('.captcha-container')) { debugLog('验证码图片,跳过回收'); return false; } if (img.dataset.skipRecycle === 'true') { debugLog('图片标记为不可回收'); return false; } const rect = img.getBoundingClientRect(); const shouldRecycle = rect.bottom < -config.features.resourceRecycling.scrollRecycleMargin || rect.top > window.innerHeight + config.features.resourceRecycling.scrollRecycleMargin; if (shouldRecycle) { debugLog(`图片符合回收条件: ${img.dataset.src || img.src}`); } return shouldRecycle; } }; // 启动内存监控 const startMemoryMonitor = () => { if (window.performance && performance.memory) { debugLog('启动内存监控'); memoryMonitor = setInterval(() => { const usedJSHeap = performance.memory.usedJSHeapSize; const totalJSHeap = performance.memory.totalJSHeapSize; if (totalJSHeap > 0) { const usagePercent = (usedJSHeap / totalJSHeap) * 100; if (usagePercent > recycleThreshold) { debugWarn(`内存使用率过高: ${usagePercent.toFixed(1)}% > ${recycleThreshold}%,触发资源回收`); triggerRecycling(); } } }, config.features.resourceRecycling.monitorInterval); } else { debugWarn('浏览器不支持performance.memory,内存监控不可用'); } }; // 触发资源回收 publicAPI.triggerRecycling = () => { if (!recyclingGuard.canRecycle()) { return; } debugLog('开始资源回收'); let recycledCount = 0; // 图片资源回收 document.querySelectorAll('img[data-src]').forEach(img => { if (imageRecycling.condition(img)) { imageRecycling.recycle(img); recycledCount++; } }); // 视频资源回收 if (config.features.videoRecycling.enabled) { const videos = Array.from(document.querySelectorAll('video')); // 按可见性排序(从最不可见到最可见) videos.sort((a, b) => { const rectA = a.getBoundingClientRect(); const rectB = b.getBoundingClientRect(); const distanceA = Math.min( Math.abs(rectA.top - window.innerHeight), Math.abs(rectA.bottom) ); const distanceB = Math.min( Math.abs(rectB.top - window.innerHeight), Math.abs(rectB.bottom) ); return distanceB - distanceA; // 降序排序 }); // 回收超出最大限制的视频 const maxVideos = config.features.resourceRecycling.maxBackgroundVideos; for (let i = maxVideos; i < videos.length; i++) { const video = videos[i]; if (videoRecycling.condition(video)) { videoRecycling.recycle(video); recycledCount++; } } } // 强制垃圾回收 if (window.gc) { window.gc(); debugLog('已执行强制垃圾回收'); } debugLog(`资源回收完成,释放了${recycledCount}个资源`); }; // 集成到懒加载系统 const patchLazyLoad = () => { if (!('IntersectionObserver' in window)) { debugLog('浏览器不支持IntersectionObserver,跳过懒加载补丁'); return; } debugLog('修补懒加载系统以支持资源回收'); const originalObserve = IntersectionObserver.prototype.observe; IntersectionObserver.prototype.observe = function(element) { resourceMap.set(element, this); originalObserve.call(this, element); }; IntersectionObserver.prototype.unobserveAndRecycle = function(element) { if (imageRecycling.condition(element)) { imageRecycling.recycle(element); } this.unobserve(element); }; }; // 视频恢复系统 const initVideoRestoration = () => { if (!config.features.videoRecycling.restoreOnScroll) { debugLog('滚动恢复视频功能已禁用'); return; } debugLog('初始化视频滚动恢复系统'); const videoObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const video = entry.target; if (video.dataset.recycledState) { videoRecycling.restore(video); videoObserver.unobserve(video); } } }); }, { rootMargin: '200px' }); const videos = document.querySelectorAll('video[data-recycled-state]'); videos.forEach(video => { videoObserver.observe(video); }); debugLog(`已监控${videos.length}个回收的视频`); }; // 关键视频保护 const protectKeyVideos = () => { const players = document.querySelectorAll('.video-player, .player-container'); let protectedCount = 0; players.forEach(container => { const video = container.querySelector('video'); if (video) { video.dataset.protected = 'true'; protectedCount++; } }); document.addEventListener('play', (e) => { if (e.target.tagName === 'VIDEO') { e.target.dataset.userActivated = 'true'; debugLog(`视频用户激活: ${e.target.id || e.target.src || '匿名视频'}`); } }, true); debugLog(`已保护${protectedCount}个关键视频播放器`); }; // 初始化 startMemoryMonitor(); patchLazyLoad(); initVideoRestoration(); protectKeyVideos(); // 清理钩子 window.addEventListener('beforeunload', () => { if (memoryMonitor) clearInterval(memoryMonitor); debugLog('资源回收系统已清理'); }); }; // ======================== // 网络感知配置应用 // ======================== const applyNetworkAwareConfig = () => { if (!config.networkAware.enabled) { debugLog('网络感知配置已禁用'); return; } if (!navigator.connection) { debugWarn('浏览器不支持网络连接API'); return; } debugLog('应用网络感知配置'); const connection = navigator.connection; const effectiveType = connection.effectiveType; const connectionConfig = config.networkAware.connectionTypes[effectiveType]; if (connectionConfig) { if (connectionConfig.preload !== undefined) { const original = config.features.preload.enabled; config.features.preload.enabled = connectionConfig.preload; debugLog(`网络类型 ${effectiveType}: 预加载 ${original} -> ${connectionConfig.preload}`); } if (connectionConfig.lazyMargin) { const original = config.features.lazyLoad.rootMargin; config.features.lazyLoad.rootMargin = connectionConfig.lazyMargin; debugLog(`网络类型 ${effectiveType}: 懒加载边距 ${original} -> ${connectionConfig.lazyMargin}`); } if (connectionConfig.maxPreloads) { const original = config.features.preload.maxPreloads; config.features.preload.maxPreloads = connectionConfig.maxPreloads; debugLog(`网络类型 ${effectiveType}: 最大预加载数 ${original} -> ${connectionConfig.maxPreloads}`); } } // 节省数据模式 if (connection.saveData) { const preloadOriginal = config.features.preload.enabled; const preconnectOriginal = config.features.preconnect.enabled; config.features.preload.enabled = false; config.features.preconnect.enabled = false; debugLog(`节省数据模式激活: 预加载 ${preloadOriginal} -> false, 预连接 ${preconnectOriginal} -> false`); } }; // ======================== // 错误处理 // ======================== const initErrorHandling = () => { debugLog('初始化错误处理系统'); // 全局错误捕获 window.addEventListener('error', (event) => { if (event.message && event.message.includes('cross-origin')) { debugWarn(`跨域资源加载错误: ${event.message}`, event.filename); // 尝试修复常见CORS问题 if (event.target && event.target.tagName === 'IMG') { event.target.crossOrigin = 'anonymous'; event.target.src = event.target.src + '?retry=' + Date.now(); debugLog(`尝试修复CORS问题: ${event.target.src}`); } } }, true); // 脚本执行错误 window.addEventListener('error', (event) => { debugError(`脚本执行错误: ${event.message}`, event.filename, event.lineno); }); // Promise未捕获错误 window.addEventListener('unhandledrejection', (event) => { debugError(`未处理的Promise拒绝: ${event.reason}`); }); }; // ======================== // CSP兼容性检测 // ======================== const checkCSPCompatibility = () => { debugLog('检测CSP兼容性'); try { const testScript = document.createElement('script'); testScript.textContent = 'window._cspTest = true;'; document.head.appendChild(testScript); const isRestricted = !window._cspTest; delete window._cspTest; if (isRestricted) { debugWarn('页面有严格的CSP策略,禁用部分优化'); } return isRestricted; } catch (e) { debugWarn('CSP检测失败', e); return true; } }; // ======================== // 中国平台后处理 // ======================== const applyChinaPlatformPostProcessing = () => { const platform = isChinaPlatform(); if (!platform) return; debugLog(`执行中国平台后处理: ${platform}`); // 平台特定后处理 switch(platform) { case 'taobao': // 轮播图优化 const gallery = document.querySelector('.J_TModule'); if (gallery) { gallery.dataset.optimizeLayout = 'true'; debugLog('淘宝轮播图优化已应用'); } break; case 'jd': // 预加载核心资源 const jdLogo = '//img11.360buyimg.com/jdphoto/jfs/t1/123246/36/2096/17041/5ec2a9c6E0d7a4ff0/6d1e8d1e3e5b3b7f.png'; if (!document.querySelector(`link[href="${jdLogo}"]`)) { const link = document.createElement('link'); link.rel = 'preload'; link.href = jdLogo; link.as = 'image'; document.head.appendChild(link); debugLog('京东Logo已预加载'); } break; case 'douyin': // 短视频列表优化 const videoList = document.querySelector('.video-list'); if (videoList) { videoList.dataset.optimizeLayout = 'true'; debugLog('抖音视频列表优化已应用'); } break; case 'bilibili': // 弹幕优化 const danmu = document.querySelector('.bpx-player-dm-wrap'); if (danmu) { danmu.dataset.optimizeLayout = 'true'; debugLog('哔哩哔哩弹幕优化已应用'); } break; case 'kuaishou': // 直播流优化 const liveStream = document.querySelector('.live-player'); if (liveStream) { liveStream.dataset.optimizeLayout = 'true'; debugLog('快手直播流优化已应用'); } break; case 'tencent': // 腾讯视频广告优化 const adContainer = document.querySelector('.txp_ad'); if (adContainer) { adContainer.dataset.optimizeLayout = 'true'; debugLog('腾讯视频广告优化已应用'); } break; } }; // ======================== // 初始化系统 // ======================== document.addEventListener('DOMContentLoaded', () => { // 调试日志初始化 if (config.debug) { console.log('[Optimizer] 脚本初始化开始'); } debugLog('DOMContentLoaded - 开始初始化'); // 1. 错误处理 initErrorHandling(); // 2. 中国平台优化(最先执行) if (config.chinaPlatforms.enabled) { applyChinaPlatformOptimizations(); } // 3. 网络感知配置 applyNetworkAwareConfig(); // 4. CSP检测 const isStrictCSP = checkCSPCompatibility(); // 5. 验证码保护 initCaptchaProtection(); // 6. 主优化模块 if (!isStrictCSP) { initSmartPreconnect(); initResourcePreload(); } // 7. 其他优化 initLazyLoad(); initLayoutStabilization(); // 8. 资源回收系统 if (config.features.resourceRecycling.enabled) { initResourceRecycling(); } // 9. 中国平台后处理 if (config.chinaPlatforms.enabled && isChinaPlatform()) { setTimeout(applyChinaPlatformPostProcessing, 2000); } // 10. 添加控制台调试命令 if (config.debug) { console.log('[Optimizer] 脚本初始化完成'); console.log('控制台命令: optimizerStatus(), checkChinaPlatform(), disableOptimizer(), forceRecycle()'); } }); // ======================== // 控制台调试命令 // ======================== const addConsoleCommands = () => { debugLog('添加控制台调试命令'); // 优化状态查看 window.optimizerStatus = () => { const status = { lazyLoad: { enabled: config.features.lazyLoad.enabled, images: document.querySelectorAll('img[data-src]').length }, preconnect: { enabled: config.features.preconnect.enabled, connections: document.querySelectorAll('link[rel="preconnect"]').length }, preload: { enabled: config.features.preload.enabled, resources: document.querySelectorAll('link[rel="preload"]').length }, resourceRecycling: { enabled: config.features.resourceRecycling.enabled, recycled: document.querySelectorAll('img[data-src]:not([src]), video[data-recycled-state]').length }, chinaPlatform: isChinaPlatform() || '未检测到' }; console.groupCollapsed('[Optimizer] 当前状态'); console.table(status); console.groupEnd(); return status; }; // 中国平台检测 window.checkChinaPlatform = () => { const platform = isChinaPlatform(); if (platform) { console.log(`检测到中国平台: ${platform}`); } else { console.log('未检测到支持的中国平台'); } return platform; }; // 临时禁用优化器 window.disableOptimizer = () => { Object.keys(config.features).forEach(key => { config.features[key].enabled = false; }); console.warn('优化器已临时禁用,刷新页面后恢复'); }; // 强制资源回收 window.forceRecycle = () => { if (config.features.resourceRecycling.enabled) { triggerRecycling(); } else { console.warn('资源回收功能未启用'); } }; console.log('可用命令: optimizerStatus(), checkChinaPlatform(), disableOptimizer(), forceRecycle()'); }; // 添加调试错误函数 const debugError = (...args) => { if (config.debug) { console.error('[Optimizer]', ...args); } }; })();