Files
argon-theme/argon-performance.test.html
nanhaoluo 9fca9481ae feat: 实现 ArgonRenderOptimizer 类
- 实现构造函数,初始化读写队列和调度状态
- 实现 read() 方法:将 DOM 读取操作加入队列
- 实现 write() 方法:将 DOM 写入操作加入队列
- 实现 _schedule() 私有方法:使用 requestAnimationFrame 调度执行
- 实现 _flush() 私有方法:批量执行队列操作(先读后写)
- 实现 enableGPU() 方法:设置 will-change 属性启用 GPU 加速
- 实现 disableGPU() 方法:移除 will-change 属性释放资源
- 添加错误处理机制,确保单个操作失败不影响其他操作
- 在测试文件中添加完整的渲染优化模块测试
- 创建使用指南文档 RENDER_OPTIMIZER_USAGE.md
- 导出 ArgonRenderOptimizer 类供其他模块使用

验证需求:2.3, 2.4, 17.1, 17.2
2026-01-21 14:52:50 +08:00

588 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Argon 性能优化模块 - 基础测试</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background: #f5f5f5;
}
.test-section {
background: white;
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.test-section h2 {
margin-top: 0;
color: #333;
border-bottom: 2px solid #4CAF50;
padding-bottom: 10px;
}
.test-result {
padding: 10px;
margin: 10px 0;
border-radius: 4px;
font-family: monospace;
}
.test-result.pass {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.test-result.fail {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
.test-result.info {
background: #d1ecf1;
color: #0c5460;
border: 1px solid #bee5eb;
}
button {
background: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
margin: 5px;
}
button:hover {
background: #45a049;
}
#test-elements {
display: none;
}
</style>
</head>
<body>
<h1>🚀 Argon 性能优化模块 - 基础测试</h1>
<!-- 测试用的 DOM 元素 -->
<div id="test-elements">
<div class="navbar">Navbar</div>
<div id="content">Content</div>
<div id="leftbar">Leftbar</div>
<div id="sidebar">Sidebar</div>
<div id="fabtn_back_to_top">Back to Top</div>
<div id="fabtn_reading_progress">Reading Progress</div>
<div id="comments">Comments</div>
<div id="post_comment">Post Comment</div>
</div>
<!-- DOM 缓存测试 -->
<div class="test-section">
<h2>1. DOM 缓存模块测试</h2>
<button onclick="testDOMCache()">运行测试</button>
<div id="dom-cache-results"></div>
</div>
<!-- 事件管理测试 -->
<div class="test-section">
<h2>2. 事件管理模块测试</h2>
<button onclick="testEventManager()">运行测试</button>
<div id="event-manager-results"></div>
</div>
<!-- 节流测试 -->
<div class="test-section">
<h2>3. 节流Throttle功能测试</h2>
<button onclick="testThrottle()">运行测试</button>
<div id="throttle-results"></div>
</div>
<!-- 防抖测试 -->
<div class="test-section">
<h2>4. 防抖Debounce功能测试</h2>
<button onclick="testDebounce()">运行测试</button>
<div id="debounce-results"></div>
</div>
<!-- 资源加载测试 -->
<div class="test-section">
<h2>5. 资源加载模块测试</h2>
<button onclick="testResourceLoader()">运行测试</button>
<div id="resource-loader-results"></div>
<!-- 测试用的元素 -->
<div style="display: none;">
<pre><code>console.log('test');</code></pre>
<div class="post-content"><img src="test.jpg" alt="test"></div>
<div data-tippy-content="Test tooltip">Hover me</div>
</div>
</div>
<!-- 渲染优化测试 -->
<div class="test-section">
<h2>6. 渲染优化模块测试</h2>
<button onclick="testRenderOptimizer()">运行测试</button>
<div id="render-optimizer-results"></div>
<div id="test-animation-element" style="width: 100px; height: 100px; background: #4CAF50; margin: 10px 0;"></div>
</div>
<!-- 综合测试 -->
<div class="test-section">
<h2>7. 综合测试</h2>
<button onclick="runAllTests()">运行所有测试</button>
<div id="all-tests-results"></div>
</div>
<!-- 加载性能优化模块 -->
<script src="argon-performance.js"></script>
<script>
// 工具函数:输出测试结果
function logResult(containerId, message, type = 'info') {
const container = document.getElementById(containerId);
const div = document.createElement('div');
div.className = `test-result ${type}`;
div.textContent = message;
container.appendChild(div);
}
function clearResults(containerId) {
document.getElementById(containerId).innerHTML = '';
}
// 测试 1: DOM 缓存模块
function testDOMCache() {
clearResults('dom-cache-results');
logResult('dom-cache-results', '开始测试 DOM 缓存模块...', 'info');
try {
// 创建实例
const cache = new ArgonDOMCache();
logResult('dom-cache-results', '✓ ArgonDOMCache 实例创建成功', 'pass');
// 测试初始化
cache.init();
if (cache.initialized) {
logResult('dom-cache-results', '✓ 缓存初始化成功', 'pass');
} else {
logResult('dom-cache-results', '✗ 缓存初始化失败', 'fail');
}
// 测试获取存在的元素
const toolbar = cache.get('toolbar');
if (toolbar && toolbar.classList.contains('navbar')) {
logResult('dom-cache-results', '✓ 成功获取缓存的 toolbar 元素', 'pass');
} else {
logResult('dom-cache-results', '✗ 获取 toolbar 元素失败', 'fail');
}
// 测试获取不存在的元素
const nonExistent = cache.get('non-existent');
if (nonExistent === null) {
logResult('dom-cache-results', '✓ 不存在的元素正确返回 null', 'pass');
} else {
logResult('dom-cache-results', '✗ 不存在的元素应返回 null', 'fail');
}
// 测试设置缓存
const testElement = document.createElement('div');
cache.set('test-element', testElement);
if (cache.get('test-element') === testElement) {
logResult('dom-cache-results', '✓ 设置和获取自定义缓存成功', 'pass');
} else {
logResult('dom-cache-results', '✗ 设置自定义缓存失败', 'fail');
}
// 测试清空缓存
cache.clear();
if (!cache.initialized && cache.get('toolbar') === null) {
logResult('dom-cache-results', '✓ 清空缓存成功', 'pass');
} else {
logResult('dom-cache-results', '✗ 清空缓存失败', 'fail');
}
logResult('dom-cache-results', '✅ DOM 缓存模块测试完成', 'info');
} catch (error) {
logResult('dom-cache-results', `✗ 测试出错: ${error.message}`, 'fail');
}
}
// 测试 2: 事件管理模块
function testEventManager() {
clearResults('event-manager-results');
logResult('event-manager-results', '开始测试事件管理模块...', 'info');
try {
// 创建实例
const eventManager = new ArgonEventManager();
logResult('event-manager-results', '✓ ArgonEventManager 实例创建成功', 'pass');
// 测试添加事件监听器
let clickCount = 0;
const testElement = document.createElement('button');
const handler = () => { clickCount++; };
eventManager.on(testElement, 'click', handler);
testElement.click();
if (clickCount === 1) {
logResult('event-manager-results', '✓ 事件监听器添加和触发成功', 'pass');
} else {
logResult('event-manager-results', '✗ 事件监听器触发失败', 'fail');
}
// 测试移除事件监听器
eventManager.off(testElement, 'click');
testElement.click();
if (clickCount === 1) {
logResult('event-manager-results', '✓ 事件监听器移除成功', 'pass');
} else {
logResult('event-manager-results', '✗ 事件监听器移除失败', 'fail');
}
// 测试清空所有监听器
let count1 = 0, count2 = 0;
const elem1 = document.createElement('div');
const elem2 = document.createElement('div');
eventManager.on(elem1, 'click', () => { count1++; });
eventManager.on(elem2, 'click', () => { count2++; });
eventManager.clear();
elem1.click();
elem2.click();
if (count1 === 0 && count2 === 0) {
logResult('event-manager-results', '✓ 清空所有监听器成功', 'pass');
} else {
logResult('event-manager-results', '✗ 清空所有监听器失败', 'fail');
}
logResult('event-manager-results', '✅ 事件管理模块测试完成', 'info');
} catch (error) {
logResult('event-manager-results', `✗ 测试出错: ${error.message}`, 'fail');
}
}
// 测试 3: 节流功能
function testThrottle() {
clearResults('throttle-results');
logResult('throttle-results', '开始测试节流功能...', 'info');
try {
const eventManager = new ArgonEventManager();
let execCount = 0;
const throttledFunc = eventManager.throttle(() => {
execCount++;
}, 50);
// 快速调用 10 次
for (let i = 0; i < 10; i++) {
throttledFunc();
}
logResult('throttle-results', `立即调用 10 次,实际执行: ${execCount}`, 'info');
// 等待一段时间后检查
setTimeout(() => {
logResult('throttle-results', `等待 200ms 后,总执行次数: ${execCount}`, 'info');
if (execCount >= 1 && execCount <= 5) {
logResult('throttle-results', '✓ 节流功能正常工作(执行次数在合理范围内)', 'pass');
} else {
logResult('throttle-results', `✗ 节流功能异常(执行次数: ${execCount}`, 'fail');
}
logResult('throttle-results', '✅ 节流功能测试完成', 'info');
}, 200);
} catch (error) {
logResult('throttle-results', `✗ 测试出错: ${error.message}`, 'fail');
}
}
// 测试 4: 防抖功能
function testDebounce() {
clearResults('debounce-results');
logResult('debounce-results', '开始测试防抖功能...', 'info');
try {
const eventManager = new ArgonEventManager();
let execCount = 0;
const debouncedFunc = eventManager.debounce(() => {
execCount++;
logResult('debounce-results', `防抖函数执行,当前执行次数: ${execCount}`, 'info');
}, 100);
// 快速调用 10 次
for (let i = 0; i < 10; i++) {
debouncedFunc();
}
logResult('debounce-results', '快速调用 10 次,等待防抖延迟...', 'info');
// 等待防抖延迟后检查
setTimeout(() => {
if (execCount === 1) {
logResult('debounce-results', '✓ 防抖功能正常工作(只执行了 1 次)', 'pass');
} else {
logResult('debounce-results', `✗ 防抖功能异常(执行了 ${execCount} 次)`, 'fail');
}
// 测试取消功能
execCount = 0;
debouncedFunc();
debouncedFunc.cancel();
setTimeout(() => {
if (execCount === 0) {
logResult('debounce-results', '✓ 防抖取消功能正常工作', 'pass');
} else {
logResult('debounce-results', '✗ 防抖取消功能失败', 'fail');
}
logResult('debounce-results', '✅ 防抖功能测试完成', 'info');
}, 150);
}, 150);
} catch (error) {
logResult('debounce-results', `✗ 测试出错: ${error.message}`, 'fail');
}
}
// 测试 5: 资源加载模块
function testResourceLoader() {
clearResults('resource-loader-results');
logResult('resource-loader-results', '开始测试资源加载模块...', 'info');
try {
// 创建实例
const loader = new ArgonResourceLoader();
logResult('resource-loader-results', '✓ ArgonResourceLoader 实例创建成功', 'pass');
// 测试 needsLibrary 方法
const needsPrism = loader.needsLibrary('pre code');
if (needsPrism) {
logResult('resource-loader-results', '✓ needsLibrary 检测到页面包含代码块', 'pass');
} else {
logResult('resource-loader-results', '✗ needsLibrary 未能检测到代码块', 'fail');
}
const needsZoomify = loader.needsLibrary('.post-content img');
if (needsZoomify) {
logResult('resource-loader-results', '✓ needsLibrary 检测到页面包含图片', 'pass');
} else {
logResult('resource-loader-results', '✗ needsLibrary 未能检测到图片', 'fail');
}
const needsTippy = loader.needsLibrary('[data-tippy-content]');
if (needsTippy) {
logResult('resource-loader-results', '✓ needsLibrary 检测到页面包含提示框元素', 'pass');
} else {
logResult('resource-loader-results', '✗ needsLibrary 未能检测到提示框元素', 'fail');
}
// 测试不存在的元素
const needsNonExistent = loader.needsLibrary('.non-existent-element');
if (!needsNonExistent) {
logResult('resource-loader-results', '✓ needsLibrary 正确返回 false不存在的元素', 'pass');
} else {
logResult('resource-loader-results', '✗ needsLibrary 应返回 false', 'fail');
}
// 测试 loadScript 方法(使用测试 URL
logResult('resource-loader-results', '测试 loadScript 方法...', 'info');
// 创建一个测试脚本
const testScriptContent = 'window.testLibLoaded = true;';
const blob = new Blob([testScriptContent], { type: 'application/javascript' });
const testUrl = URL.createObjectURL(blob);
loader.loadScript('test-lib', testUrl)
.then(() => {
if (window.testLibLoaded) {
logResult('resource-loader-results', '✓ loadScript 成功加载脚本', 'pass');
} else {
logResult('resource-loader-results', '✗ loadScript 加载脚本失败', 'fail');
}
// 测试缓存机制
if (loader.loaded.has('test-lib')) {
logResult('resource-loader-results', '✓ 加载的脚本已添加到缓存', 'pass');
} else {
logResult('resource-loader-results', '✗ 脚本未添加到缓存', 'fail');
}
// 测试重复加载
const startTime = Date.now();
return loader.loadScript('test-lib', testUrl).then(() => {
const loadTime = Date.now() - startTime;
if (loadTime < 10) {
logResult('resource-loader-results', '✓ 重复加载使用缓存(立即返回)', 'pass');
} else {
logResult('resource-loader-results', `⚠ 重复加载耗时 ${loadTime}ms可能未使用缓存`, 'fail');
}
});
})
.then(() => {
// 测试加载失败的情况
return loader.loadScript('invalid-lib', 'https://invalid-url-that-does-not-exist.com/script.js')
.then(() => {
logResult('resource-loader-results', '✗ 加载失败应该抛出错误', 'fail');
})
.catch((error) => {
if (error.message.includes('Failed to load')) {
logResult('resource-loader-results', '✓ 加载失败正确抛出错误', 'pass');
} else {
logResult('resource-loader-results', '✗ 错误信息不正确', 'fail');
}
});
})
.then(() => {
logResult('resource-loader-results', '✅ 资源加载模块测试完成', 'info');
URL.revokeObjectURL(testUrl);
})
.catch((error) => {
logResult('resource-loader-results', `✗ 测试出错: ${error.message}`, 'fail');
});
} catch (error) {
logResult('resource-loader-results', `✗ 测试出错: ${error.message}`, 'fail');
}
}
// 测试 6: 渲染优化模块
function testRenderOptimizer() {
clearResults('render-optimizer-results');
logResult('render-optimizer-results', '开始测试渲染优化模块...', 'info');
try {
// 创建实例
const optimizer = new ArgonRenderOptimizer();
logResult('render-optimizer-results', '✓ ArgonRenderOptimizer 实例创建成功', 'pass');
// 测试读写队列
let readValue = 0;
let writeValue = 0;
optimizer.read(() => {
readValue = document.body.offsetHeight; // 读取操作
logResult('render-optimizer-results', `读取操作执行,获取高度: ${readValue}px`, 'info');
});
optimizer.write(() => {
const testDiv = document.createElement('div');
testDiv.textContent = '测试写入操作';
writeValue = 1;
logResult('render-optimizer-results', '写入操作执行', 'info');
});
// 等待 requestAnimationFrame 执行
setTimeout(() => {
if (readValue > 0 && writeValue === 1) {
logResult('render-optimizer-results', '✓ 读写队列正常工作', 'pass');
} else {
logResult('render-optimizer-results', '✗ 读写队列执行失败', 'fail');
}
// 测试批量操作顺序
const operations = [];
optimizer.read(() => {
operations.push('read1');
});
optimizer.write(() => {
operations.push('write1');
});
optimizer.read(() => {
operations.push('read2');
});
optimizer.write(() => {
operations.push('write2');
});
setTimeout(() => {
const expectedOrder = ['read1', 'read2', 'write1', 'write2'];
const orderCorrect = JSON.stringify(operations) === JSON.stringify(expectedOrder);
if (orderCorrect) {
logResult('render-optimizer-results', '✓ 批量操作顺序正确(先读后写)', 'pass');
} else {
logResult('render-optimizer-results', `✗ 操作顺序错误: ${operations.join(', ')}`, 'fail');
}
// 测试 GPU 加速
const testElement = document.getElementById('test-animation-element');
optimizer.enableGPU(testElement);
const willChangeEnabled = testElement.style.willChange === 'transform, opacity';
if (willChangeEnabled) {
logResult('render-optimizer-results', '✓ enableGPU 正确设置 will-change 属性', 'pass');
} else {
logResult('render-optimizer-results', '✗ enableGPU 设置失败', 'fail');
}
optimizer.disableGPU(testElement);
const willChangeDisabled = testElement.style.willChange === 'auto';
if (willChangeDisabled) {
logResult('render-optimizer-results', '✓ disableGPU 正确移除 will-change 属性', 'pass');
} else {
logResult('render-optimizer-results', '✗ disableGPU 移除失败', 'fail');
}
// 测试错误处理
optimizer.read(() => {
throw new Error('测试错误');
});
optimizer.write(() => {
logResult('render-optimizer-results', '✓ 错误处理正常,后续操作继续执行', 'pass');
});
setTimeout(() => {
logResult('render-optimizer-results', '✅ 渲染优化模块测试完成', 'info');
}, 100);
}, 100);
}, 100);
} catch (error) {
logResult('render-optimizer-results', `✗ 测试出错: ${error.message}`, 'fail');
}
}
// 运行所有测试
function runAllTests() {
clearResults('all-tests-results');
logResult('all-tests-results', '🚀 开始运行所有测试...', 'info');
testDOMCache();
testEventManager();
testThrottle();
testDebounce();
testResourceLoader();
testRenderOptimizer();
setTimeout(() => {
logResult('all-tests-results', '✅ 所有测试已启动,请查看各模块的测试结果', 'info');
}, 500);
}
// 页面加载完成后的提示
window.addEventListener('load', () => {
console.log('Argon 性能优化模块测试页面已加载');
console.log('ArgonPerformanceConfig:', ArgonPerformanceConfig);
});
</script>
</body>
</html>