- 删除临时测试文件 (test-*.html, test-*.js) - 删除临时文档文件 (GPU_ACCELERATION_USAGE.md, RENDER_OPTIMIZER_USAGE.md) - 删除测试 HTML 文件 (argon-memory-manager.test.html, argon-performance.test.html) - 整理文档到 specs 目录下
289 lines
14 KiB
Markdown
289 lines
14 KiB
Markdown
# 需求文档
|
||
|
||
## 简介
|
||
|
||
Argon WordPress 主题在某些场景下会出现高 CPU 占用问题,影响用户体验和设备性能。通过分析主题的核心文件(style.css ~12000 行、argontheme.js ~3700 行、functions.php ~5700 行),识别出以下关键性能瓶颈:
|
||
|
||
**JavaScript 执行性能问题:**
|
||
- 频繁的 DOM 查询和操作未使用缓存
|
||
- 滚动和 resize 事件处理器未使用节流/防抖
|
||
- 复杂的选择器查询(如 `querySelectorAll`)在循环中重复执行
|
||
- 大量同步操作阻塞主线程
|
||
|
||
**CSS 渲染性能问题:**
|
||
- 复杂的 CSS 选择器导致样式计算耗时
|
||
- 过度使用 box-shadow 和 filter 等高成本属性
|
||
- 动画未充分利用 GPU 加速
|
||
- 重排(reflow)和重绘(repaint)频繁触发
|
||
|
||
**资源加载问题:**
|
||
- 第三方库(Prism、Tippy、Zoomify 等)加载时机不当
|
||
- 字体文件加载阻塞渲染
|
||
- 未使用资源预加载和预连接
|
||
- 关键 CSS 未内联
|
||
|
||
**内存管理问题:**
|
||
- 事件监听器未正确清理导致内存泄漏
|
||
- 闭包引用导致对象无法被垃圾回收
|
||
- 大型数据结构未及时释放
|
||
- 定时器和动画帧未正确取消
|
||
|
||
本规范旨在系统性地优化主题的资源使用和 CPU 占用,提升整体性能和用户体验。
|
||
|
||
## 术语表
|
||
|
||
- **DOM_Cache**: DOM 元素缓存系统,避免重复查询
|
||
- **Event_Throttle**: 事件节流机制,限制事件处理器执行频率
|
||
- **Event_Debounce**: 事件防抖机制,延迟执行直到事件停止触发
|
||
- **GPU_Acceleration**: 利用 GPU 进行图形渲染加速
|
||
- **Critical_CSS**: 首屏渲染所需的关键 CSS
|
||
- **Resource_Hints**: 资源提示(preload、prefetch、preconnect 等)
|
||
- **Render_Blocking**: 阻塞渲染的资源
|
||
- **Memory_Leak**: 内存泄漏,程序无法释放不再使用的内存
|
||
- **Main_Thread**: 浏览器主线程,负责 JavaScript 执行和渲染
|
||
- **Layout_Thrashing**: 布局抖动,频繁的读写 DOM 导致多次重排
|
||
- **Paint_Complexity**: 绘制复杂度,影响渲染性能的因素
|
||
- **Composite_Layer**: 合成层,GPU 加速的独立渲染层
|
||
|
||
## 需求
|
||
|
||
### 需求 1: DOM 查询优化
|
||
|
||
**用户故事:** 作为主题开发者,我希望减少重复的 DOM 查询,以降低 CPU 占用和提升响应速度。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 页面初始化时 THEN THE DOM_Cache SHALL 缓存所有频繁访问的 DOM 元素引用
|
||
2. WHEN 需要访问 DOM 元素时 THEN THE System SHALL 优先使用缓存而非重新查询
|
||
3. WHEN PJAX 页面切换时 THEN THE DOM_Cache SHALL 清空旧缓存并重新建立新页面的缓存
|
||
4. WHEN 使用 `querySelectorAll` 时 THEN THE System SHALL 避免在循环中重复执行
|
||
5. WHEN 元素不存在时 THEN THE DOM_Cache SHALL 返回 null 而非抛出异常
|
||
|
||
### 需求 2: 滚动事件性能优化
|
||
|
||
**用户故事:** 作为用户,我希望页面滚动时流畅不卡顿,CPU 占用保持在合理范围。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 绑定滚动事件监听器时 THEN THE Event_Throttle SHALL 限制处理器执行频率为最多每 16ms 一次
|
||
2. WHEN 滚动事件触发时 THEN THE System SHALL 使用 `requestAnimationFrame` 同步浏览器渲染周期
|
||
3. WHEN 滚动处理器执行时 THEN THE System SHALL 批量读取 DOM 属性,避免布局抖动
|
||
4. WHEN 滚动处理器需要修改 DOM 时 THEN THE System SHALL 在读取完成后统一写入
|
||
5. WHEN 页面卸载时 THEN THE System SHALL 移除所有滚动事件监听器
|
||
|
||
### 需求 3: Resize 事件性能优化
|
||
|
||
**用户故事:** 作为用户,我希望调整浏览器窗口大小时页面能快速响应,不会出现明显延迟。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 绑定 resize 事件监听器时 THEN THE Event_Debounce SHALL 延迟执行直到窗口大小停止变化 150ms
|
||
2. WHEN resize 事件触发时 THEN THE System SHALL 取消之前的待执行任务
|
||
3. WHEN resize 处理器执行时 THEN THE System SHALL 批量更新所有需要调整的布局
|
||
4. WHEN 瀑布流布局需要重新计算时 THEN THE System SHALL 使用 Web Worker 进行计算(如果可行)
|
||
5. WHEN 移动端方向改变时 THEN THE System SHALL 延迟 300ms 后再执行布局调整
|
||
|
||
### 需求 4: CSS 选择器优化
|
||
|
||
**用户故事:** 作为主题开发者,我希望优化 CSS 选择器,减少样式计算时间。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 编写 CSS 选择器时 THEN THE System SHALL 避免使用通配符选择器(`*`)
|
||
2. WHEN 编写 CSS 选择器时 THEN THE System SHALL 避免过深的嵌套(最多 3 层)
|
||
3. WHEN 编写 CSS 选择器时 THEN THE System SHALL 优先使用类选择器而非标签选择器
|
||
4. WHEN 使用属性选择器时 THEN THE System SHALL 避免使用正则表达式匹配(`*=`、`^=`、`$=`)
|
||
5. WHEN 样式需要高性能时 THEN THE System SHALL 使用 BEM 命名规范提高选择器效率
|
||
|
||
### 需求 5: 动画性能优化
|
||
|
||
**用户故事:** 作为用户,我希望页面动画流畅运行在 60fps,不会导致 CPU 占用过高。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 实现动画效果时 THEN THE GPU_Acceleration SHALL 仅使用 `transform` 和 `opacity` 属性
|
||
2. WHEN 元素需要动画时 THEN THE System SHALL 使用 `will-change` 提示浏览器创建合成层
|
||
3. WHEN 动画完成时 THEN THE System SHALL 移除 `will-change` 属性释放资源
|
||
4. WHEN 使用 CSS 动画时 THEN THE System SHALL 避免动画 `width`、`height`、`margin` 等触发重排的属性
|
||
5. WHEN 页面有多个动画时 THEN THE System SHALL 限制同时运行的动画数量不超过 3 个
|
||
|
||
### 需求 6: 高成本 CSS 属性优化
|
||
|
||
**用户故事:** 作为主题开发者,我希望减少高成本 CSS 属性的使用,降低渲染负担。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 使用 `box-shadow` 时 THEN THE System SHALL 限制阴影数量不超过 2 个
|
||
2. WHEN 使用 `filter` 效果时 THEN THE System SHALL 仅在必要时应用,并考虑使用图片替代
|
||
3. WHEN 使用 `backdrop-filter` 时 THEN THE System SHALL 限制模糊半径不超过 10px
|
||
4. WHEN 使用渐变背景时 THEN THE System SHALL 考虑使用纯色或图片替代复杂渐变
|
||
5. WHEN 元素需要圆角时 THEN THE System SHALL 避免在大型元素上使用过大的 `border-radius`
|
||
|
||
### 需求 7: 第三方库加载优化
|
||
|
||
**用户故事:** 作为用户,我希望第三方库按需加载,不会在不需要时占用资源。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 页面不包含代码块时 THEN THE System SHALL 不加载 Prism 代码高亮库
|
||
2. WHEN 页面不包含图片时 THEN THE System SHALL 不加载 Zoomify 图片放大库
|
||
3. WHEN 页面不包含提示框时 THEN THE System SHALL 不加载 Tippy 提示框库
|
||
4. WHEN 第三方库需要加载时 THEN THE System SHALL 使用动态 import 或异步脚本标签
|
||
5. WHEN 第三方库加载完成时 THEN THE System SHALL 缓存实例避免重复初始化
|
||
|
||
### 需求 8: 字体加载优化
|
||
|
||
**用户故事:** 作为用户,我希望字体加载不会阻塞页面渲染,且能快速显示文本内容。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 加载自定义字体时 THEN THE System SHALL 使用 `font-display: swap` 策略
|
||
2. WHEN 字体文件较大时 THEN THE System SHALL 使用 `preload` 提示预加载关键字体
|
||
3. WHEN 字体加载失败时 THEN THE System SHALL 优雅降级到系统字体
|
||
4. WHEN 使用图标字体时 THEN THE System SHALL 考虑使用 SVG sprite 替代
|
||
5. WHEN 字体子集化可行时 THEN THE System SHALL 仅加载使用的字符集
|
||
|
||
### 需求 9: 关键 CSS 内联
|
||
|
||
**用户故事:** 作为用户,我希望首屏内容能快速渲染,不会因为 CSS 加载而出现白屏。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 页面加载时 THEN THE Critical_CSS SHALL 内联在 HTML 的 `<head>` 中
|
||
2. WHEN 提取关键 CSS 时 THEN THE System SHALL 包含首屏可见元素的所有样式
|
||
3. WHEN 非关键 CSS 加载时 THEN THE System SHALL 使用异步加载避免阻塞渲染
|
||
4. WHEN 关键 CSS 大小超过 14KB 时 THEN THE System SHALL 进一步优化减少体积
|
||
5. WHEN 不同页面类型时 THEN THE System SHALL 提取对应的关键 CSS
|
||
|
||
### 需求 10: 资源预加载优化
|
||
|
||
**用户故事:** 作为用户,我希望浏览器能智能预加载资源,提升页面加载速度。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 页面加载时 THEN THE Resource_Hints SHALL 使用 `preconnect` 预连接第三方域名
|
||
2. WHEN 关键资源需要加载时 THEN THE Resource_Hints SHALL 使用 `preload` 提前加载
|
||
3. WHEN 用户可能访问的页面时 THEN THE Resource_Hints SHALL 使用 `prefetch` 预取资源
|
||
4. WHEN 使用 DNS 预解析时 THEN THE Resource_Hints SHALL 使用 `dns-prefetch` 提前解析域名
|
||
5. WHEN 预加载资源过多时 THEN THE System SHALL 限制数量避免浪费带宽
|
||
|
||
### 需求 11: 事件监听器内存泄漏修复
|
||
|
||
**用户故事:** 作为主题开发者,我希望事件监听器能正确清理,避免内存泄漏。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 绑定事件监听器时 THEN THE System SHALL 使用命名函数并保存引用
|
||
2. WHEN 组件销毁时 THEN THE System SHALL 使用保存的引用移除所有事件监听器
|
||
3. WHEN 使用事件委托时 THEN THE System SHALL 在父元素上绑定单个监听器
|
||
4. WHEN PJAX 页面切换时 THEN THE System SHALL 清理所有页面特定的事件监听器
|
||
5. WHEN 使用第三方库时 THEN THE System SHALL 调用库提供的销毁方法清理监听器
|
||
|
||
### 需求 12: 闭包内存泄漏修复
|
||
|
||
**用户故事:** 作为主题开发者,我希望闭包不会导致内存泄漏,对象能被正确回收。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 创建闭包时 THEN THE System SHALL 避免捕获不必要的外部变量
|
||
2. WHEN 闭包引用 DOM 元素时 THEN THE System SHALL 在不需要时解除引用
|
||
3. WHEN 闭包引用大型对象时 THEN THE System SHALL 仅保存必要的属性
|
||
4. WHEN 组件销毁时 THEN THE System SHALL 将闭包引用的变量设置为 null
|
||
5. WHEN 使用定时器或动画帧时 THEN THE System SHALL 在清理时取消所有待执行的回调
|
||
|
||
### 需求 13: 定时器和动画帧清理
|
||
|
||
**用户故事:** 作为主题开发者,我希望定时器和动画帧能正确清理,避免资源浪费。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 使用 `setTimeout` 时 THEN THE System SHALL 保存返回的 timer ID
|
||
2. WHEN 使用 `setInterval` 时 THEN THE System SHALL 保存返回的 interval ID
|
||
3. WHEN 使用 `requestAnimationFrame` 时 THEN THE System SHALL 保存返回的 frame ID
|
||
4. WHEN 组件销毁或页面切换时 THEN THE System SHALL 使用对应的清理函数取消所有定时器和动画帧
|
||
5. WHEN 定时器回调执行时 THEN THE System SHALL 检查组件是否仍然存在
|
||
|
||
### 需求 14: 大型数据结构优化
|
||
|
||
**用户故事:** 作为主题开发者,我希望大型数据结构能高效管理,不会占用过多内存。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 存储大量数据时 THEN THE System SHALL 使用 Map 或 Set 而非普通对象
|
||
2. WHEN 数据不再需要时 THEN THE System SHALL 及时清空数据结构
|
||
3. WHEN 缓存数据时 THEN THE System SHALL 设置合理的缓存大小上限
|
||
4. WHEN 缓存超过上限时 THEN THE System SHALL 使用 LRU 策略淘汰旧数据
|
||
5. WHEN 处理大型数组时 THEN THE System SHALL 考虑分批处理避免阻塞主线程
|
||
|
||
### 需求 15: 图片资源优化
|
||
|
||
**用户故事:** 作为用户,我希望图片加载快速且不会占用过多带宽和内存。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 加载图片时 THEN THE System SHALL 根据设备像素比加载合适尺寸的图片
|
||
2. WHEN 图片支持 WebP 格式时 THEN THE System SHALL 优先加载 WebP 格式
|
||
3. WHEN 图片较大时 THEN THE System SHALL 使用渐进式 JPEG 或交错式 PNG
|
||
4. WHEN 图片不在视口时 THEN THE System SHALL 使用懒加载延迟加载
|
||
5. WHEN 图片加载完成时 THEN THE System SHALL 释放临时创建的 Image 对象
|
||
|
||
### 需求 16: JavaScript 执行优化
|
||
|
||
**用户故事:** 作为主题开发者,我希望 JavaScript 代码执行高效,不会长时间阻塞主线程。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 执行耗时操作时 THEN THE System SHALL 使用 `requestIdleCallback` 在空闲时执行
|
||
2. WHEN 处理大量数据时 THEN THE System SHALL 分批处理,每批之间让出主线程
|
||
3. WHEN 计算复杂时 THEN THE System SHALL 考虑使用 Web Worker 在后台线程执行
|
||
4. WHEN 使用循环时 THEN THE System SHALL 缓存数组长度避免重复访问
|
||
5. WHEN 操作数组时 THEN THE System SHALL 使用高效的数组方法(如 `forEach` 而非 `for...in`)
|
||
|
||
### 需求 17: 布局抖动消除
|
||
|
||
**用户故事:** 作为主题开发者,我希望消除布局抖动,减少不必要的重排和重绘。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 需要读取 DOM 属性时 THEN THE System SHALL 批量读取所有需要的属性
|
||
2. WHEN 需要修改 DOM 时 THEN THE System SHALL 在读取完成后批量写入
|
||
3. WHEN 频繁修改样式时 THEN THE System SHALL 使用 CSS 类切换而非直接修改 style 属性
|
||
4. WHEN 需要多次修改 DOM 时 THEN THE System SHALL 使用 DocumentFragment 批量插入
|
||
5. WHEN 元素需要隐藏时 THEN THE System SHALL 使用 `visibility: hidden` 或 `opacity: 0` 而非 `display: none`(如果布局允许)
|
||
|
||
### 需求 18: 性能监控和分析
|
||
|
||
**用户故事:** 作为主题开发者,我希望能监控主题的性能指标,及时发现性能问题。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 页面加载完成时 THEN THE System SHALL 使用 Performance API 记录关键性能指标
|
||
2. WHEN 检测到性能问题时 THEN THE System SHALL 在控制台输出警告信息
|
||
3. WHEN 开发模式时 THEN THE System SHALL 提供详细的性能分析数据
|
||
4. WHEN 生产模式时 THEN THE System SHALL 仅记录关键指标避免影响性能
|
||
5. WHEN 性能指标异常时 THEN THE System SHALL 提供优化建议
|
||
|
||
### 需求 19: 代码分割和按需加载
|
||
|
||
**用户故事:** 作为用户,我希望页面只加载必要的代码,减少初始加载时间。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 功能模块独立时 THEN THE System SHALL 将其拆分为独立的 JS 文件
|
||
2. WHEN 功能不是首屏必需时 THEN THE System SHALL 使用动态 import 按需加载
|
||
3. WHEN 用户交互触发功能时 THEN THE System SHALL 在交互时才加载对应模块
|
||
4. WHEN 模块加载失败时 THEN THE System SHALL 提供降级方案或友好提示
|
||
5. WHEN 模块已加载时 THEN THE System SHALL 避免重复加载
|
||
|
||
### 需求 20: 缓存策略优化
|
||
|
||
**用户故事:** 作为用户,我希望浏览器能有效缓存资源,减少重复加载。
|
||
|
||
#### 验收标准
|
||
|
||
1. WHEN 静态资源更新时 THEN THE System SHALL 使用版本号或哈希值更新文件名
|
||
2. WHEN 设置缓存策略时 THEN THE System SHALL 为不同类型资源设置合适的缓存时间
|
||
3. WHEN 资源不常变化时 THEN THE System SHALL 设置长期缓存(如 1 年)
|
||
4. WHEN 资源可能变化时 THEN THE System SHALL 使用 ETag 或 Last-Modified 进行验证
|
||
5. WHEN 使用 Service Worker 时 THEN THE System SHALL 实现智能缓存策略
|