关于 frontend-perf
frontend-perf 是面向开发者的浏览器与 Electron 前端性能参考技能,汇集指标、瓶颈模式、版本相关建议和优化优先级,可与 perf-workflow 配合使用。
主要功能
- 01RAIL、Web Vitals 与 Electron 指标参考
- 02前端性能瓶颈模式
- 03React、Angular 与 Electron 版本建议
- 04优化事项优先级参考
- 05分析与验证标准
适用场景
- 01为前端性能建立量化基线
- 02定位重排、长任务或内存增长
- 03规划 React 或 Angular 优化
- 04核验 Electron 启动和 IPC 性能
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ fudesign2008/ open-skills --skill frontend-perf安装后在 Claude Code 中输入/frontend-perf确认已加载。
附带文件reference.md
详细介绍
前端性能优化知识库
与 perf-workflow 的关系
此技能是 perf-workflow 的知识层,而 perf-workflow 是流程层;两者配合使用。
| perf-workflow 阶段 | 此技能提供的前端专属内容 |
|---|---|
| 阶段 1:性能证据 | 定量基准:RAIL / Web Vitals / Electron 指标阈值 |
| 阶段 2:性能定位 | 前端瓶颈模式表;渲染流水线定位规则 |
| 阶段 3:性能假设 | 前端专属根因(回流 / 长任务 / IPC / 内存泄漏) |
| 阶段 4:性能监控 | 适用的工具和埋点位置 |
| 阶段 5:性能优化 | 优化优先级参考(P0 → P1 → P2) |
| 阶段 6:性能验证 | 通过标准(LCP/INP/CLS/启动时间) |
定量标准速查
RAIL 模型(Google Chrome 团队推荐,W3C 推荐)
| 阶段 | 全称 | 用户感知阈值 | 核心优化方向 |
|---|---|---|---|
| R | 响应 | 交互 → 反馈 < 100ms | 精简事件处理器,绝不阻塞主线程 |
| A | 动画 | 稳定保持 60fps,每帧 < 16ms | 仅使用 transform/opacity,避免回流 |
| I | 空闲 | 将空闲工作拆分为 < 50ms 的任务块 | 使用 requestIdleCallback 调度非紧急任务 |
| L | 加载 | 首屏内容 < 2s,可用 < 5s | 减少关键资源的数量和大小 |
Web Vitals:三项核心指标(2024 年版)
| 指标 | 全称 | 良好 | 需要改进 | 优化重点 |
|---|---|---|---|---|
| LCP | 最大内容绘制 | < 2.5s | > 4s | 首屏加载、关键渲染路径 |
| INP | 下一次绘制交互延迟 | < 200ms | > 500ms | 主线程长任务、交互响应速度 |
| CLS | 累积布局偏移 | < 0.1 | > 0.25 | 布局稳定性、预留图片尺寸 |
Electron 桌面端扩展指标
| 指标 | 通过阈值(行业标准) | 定位工具 |
|---|---|---|
| 冷启动时间 | Windows < 2s,macOS < 1.5s | Electron DevTools / 埋点计时 |
| 热启动时间 | < 500ms | 埋点计时 |
| IPC 往返时间 | 每次调用 < 50ms(针对频繁调用) | IPC 日志埋点 |
| 渲染进程内存 | 无持续增长,基线稳定 | Chrome DevTools Memory 面板 |
| 主线程 CPU | 空闲时接近 0,无长任务 | Chrome DevTools Performance 面板 |
前端特有的瓶颈模式
补充 perf-workflow Stage 3 中的通用模式表;以下是前端代码中常见的具体形式:
| 模式 | 前端中的具体表现 | 典型触发场景(前端) | 定位工具 |
|---|---|---|---|
| Reflow(布局) | 读取或写入几何属性会重新触发整个渲染流水线 | 更改宽度/高度/位置;读取 offsetWidth/scrollTop 后再写入 DOM | Performance 面板中的 Layout 标记 |
| Repaint(绘制) | 更改视觉属性会触发重绘,但跳过 Layout | 更改颜色/阴影/背景 | Performance 面板中的 Paint 标记 |
| 主线程长任务 | 单个任务超过 50ms 会阻塞事件循环,使 INP 超出目标 | 在主线程上运行繁重的数据处理/复杂计算/同步 IPC | Performance 面板中的 Long Task 标记 |
| 不必要的重新渲染 | 组件的 props/state 未变,但仍触发重新渲染 | props 引用不稳定;全局状态粒度过粗;context 更新过于频繁 | React Profiler/Vue DevTools |
| IPC 阻塞 | Electron 同步 IPC 或高频 IPC 会占满主线程 | 调用 sendSync;在滚动/输入处理程序中高频发送 IPC | Electron 日志 + Performance 面板 |
| 内存持续增长 | 内存未释放,GC 无法回收,最终导致卡顿/崩溃 | 事件监听器未解绑;计时器未清除;闭包持有大型对象 | Memory 面板的 Heap Snapshot |
| 布局抖动 | 交替“读取-写入-读取-写入”DOM 属性,每次写入都会强制同步布局 | 在循环中交替读取/修改 DOM 几何属性 | Performance 面板中密集的 Layout 标记 |
| React 并发特性使用不足 | 在 React 18+ 项目中,耗时计算仍沿同步路径执行,阻塞用户输入响应 | 未使用 useTransition / startTransition 将低优先级更新标记出来 | React DevTools Profiler 时间线 |
| Angular Zone 触发过多 | Zone.js 会拦截每个异步操作,并触发整个树的变更检测 | 未使用 NgZone.runOutsideAngular() 隔离高频事件 | Angular DevTools Profiler |
按框架版本划分的关键优化特性
分析/优化时,先确认框架版本,再选择匹配的策略——不同版本的策略差异很大。
React 版本
| 版本 | 关键性能特性 | 优化效果 |
|---|---|---|
| 16.x | PureComponent / shouldComponentUpdate / 类组件 | 手动控制重新渲染;不支持 Hooks |
| 16.8+ | useMemo / useCallback / useRef / React.memo | 函数组件可以进行细粒度记忆化 |
| 18 | 并发渲染 / 自动批处理 / useTransition / useDeferredValue | 优先级调度;多次 setState 调用会自动合并;可将长任务标记为低优先级 |
| 19 | React Compiler(自动记忆化) / use() | 编译器会自动处理引用稳定性;大多数情况下不再需要手动编写 memo |
Angular 版本
| 版本 | 关键性能特性 | 优化影响 |
|---|---|---|
| 9+ | Ivy 编译器 | 更小的包体积、更快的编译速度、更利于摇树优化 |
| 14+ | 独立组件 | 减少 NgModule 开销,实现更精细的延迟加载 |
| 16+ | Signals(signal() / computed() / effect()) | 精细化响应式,可绕过 Zone.js 变更检测 |
| 17+ | @defer 块 / @for ... track | 内置延迟渲染;trackBy 已集成到模板语法中 |
| 18+ | 无 Zone 变更检测(实验性) | 移除 Zone.js 补丁,彻底消除由 Zone 触发的开销 |
Electron 版本
| 版本 | 关键性能特性 | 优化影响 |
|---|---|---|
| 12+ | remote 模块已弃用,默认启用 contextIsolation | 必须使用 contextBridge,消除 remote 的同步 IPC 开销 |
| 20+ | 默认启用 sandbox: true | 渲染器进程初始化更轻量,但需要调整预加载脚本 |
| 22+ | UtilityProcess API | CPU 密集型任务的理想运行环境,取代 child_process.fork |
| 28+ | 渲染器进程原生支持 ESM | 可使用原生 import(),实现更彻底的摇树优化 |
浏览器渲染管线要点
渲染路径:DOM → CSSOM → Style → Layout (reflow) → Paint (repaint) → Composite
| 操作类型 | 触发的最高开销阶段 | 典型 CSS 属性 | 性能等级 |
|---|---|---|---|
| 几何变化 | Layout(回流) | width / height / top / margin | 最慢 |
| 视觉变化 | Paint(重绘) | color / background / box-shadow | 中等 |
| 合成变化 | 仅 Composite | transform / opacity | 最快 |
核心规则:动画和滚动只能使用 transform / opacity;对其他属性的更改应批量执行并尽量减少。
Electron 多进程要点
| 进程类型 | 核心职责 | 阻塞影响 | 优化红线 |
|---|---|---|---|
| 主进程 | 应用生命周期、窗口管理、系统 API | 所有窗口冻结或无响应 | 不得执行同步 IO、CPU 密集型任务或紧密循环 |
| 渲染器进程 | 窗口 UI 渲染、JS 执行、用户交互 | 当前窗口冻结 | 遵循与 Web 前端相同的规则;不得使用同步 IPC |
| GPU 进程 | 3D 绘制、硬件加速、合成器图层渲染 | 动画卡顿、屏幕撕裂 | 避免过度使用硬件加速;防止合成器图层激增 |
| Worker 进程 | CPU 密集型任务、文件 IO、后台计算 | 不会影响 UI 线程 | 所有耗时任务都必须在此类进程或 Worker 中运行 |
IPC 核心规则:绝不使用 ipcRenderer.sendSync;在高频事件中对 IPC 调用进行节流;使用 SharedArrayBuffer 零拷贝传输大型数据。
优化优先级速查
优先处理耗时占比最大的步骤——即使将占比 < 10% 的步骤优化 100 倍,整体收益仍然有限(阿姆达尔定律)。
P0:优先执行(影响大、成本低)
- 拆分长任务:将超过 50ms 的同步任务拆分为小于 50ms 的块,并通过
requestIdleCallback调度 - 虚拟滚动:长列表(> 100 项)必须使用,采用 react-window / vue-virtual-scroller
- 避免回流:动画只使用 transform/opacity;先批量读取,再批量写入 DOM
- 异步 IPC:将所有 Electron IPC 转为异步;移除所有
sendSync - Web Worker:将大型数据解析、加密和复杂计算移出主线程
P1:下一步(成本适中,收益明确)
- 组件记忆化:使用 React.memo / useMemo / useCallback 稳定 props 和函数引用
- 状态粒度:拆分过于粗粒度的全局状态,缩小不必要的重新渲染范围
- 代码拆分:在路由级别 / 组件级别进行动态导入,减小首屏 JS 体积
- Electron 启动:尽可能精简主进程入口;异步加载非首屏模块
P2:可选(工程收益,长期见效)
- 缓存策略:对静态资源进行长期强缓存,并使用哈希文件名;使用 Service Worker 进行离线缓存
- 减小 Bundle 体积:进行 tree-shaking;按需导入大型库;图片使用 WebP/AVIF
- 性能预算 + CI/CD 门禁:将 LCP/INP/Bundle 体积纳入流水线,超出预算时阻止发布
详细的实现方法请参阅 reference.md。
分析工具快速参考
| 场景 | 推荐工具 |
|---|---|
| 主线程长任务 | Chrome DevTools → Performance 面板 → Long Tasks |
| 渲染瓶颈 | Chrome DevTools → Performance → Rendering 面板 |
| React 重新渲染 | React DevTools Profiler(火焰图 + 排名图表) |
| React 18+ 调度优先级 | React DevTools Profiler → 时间线视图,检查 Concurrent 优先级标记 |
| Angular 变更检测 | Angular DevTools → Profiler(检查变更检测次数和持续时间) |
| Angular Signals | Angular DevTools 17+ → Signal 依赖关系图可视化(实验性) |
| 内存泄漏 | Chrome DevTools → Memory → 对比 Heap Snapshots |
| Web Vitals | Lighthouse / Chrome DevTools → Performance Insights |
| Electron 进程概览 | 使用 app.getAppMetrics() 检查各进程的 CPU/内存;系统资源监视器 |
| Electron IPC 耗时 | 自定义日志埋点 + Chrome DevTools Performance 面板 |
| Bundle 体积分析 | webpack-bundle-analyzer / vite-plugin-inspect |
评论
支持 Markdown