关于 optimize
用于诊断和修复 Web 性能问题的设计技能,指导团队先测量、再处理瓶颈,并在不同设备和网络条件下验证改动。
主要功能
- 01测量 Core Web Vitals 和运行时指标
- 02优化加载、渲染与动画
- 03减少代码包体积和网络请求
- 04跨设备及网络验证改动
适用场景
- 01排查页面加载或交互缓慢
- 02改善移动设备及慢速网络的响应
- 03检查性能改动是否引入回归
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pbakaus/ impeccable --skill optimize安装后在 Claude Code 中输入/optimize确认已加载。
详细介绍
识别并修复性能问题,打造更快、更流畅的用户体验。
评估性能问题
了解当前性能并识别问题:
-
测量当前状态:
- Core Web Vitals:LCP、FID/INP、CLS 得分
- 加载时间:可交互时间、首次内容绘制时间
- 包体积:JavaScript、CSS、图像大小
- 运行时性能:帧率、内存使用量、CPU 使用率
- 网络:请求数量、负载大小、瀑布图
-
识别瓶颈:
- 哪些地方很慢?(初始加载?交互?动画?)
- 是什么导致的?(图像过大?JavaScript 开销过高?布局抖动?)
- 情况有多严重?(能否察觉?令人烦恼?会阻塞操作?)
- 哪些用户受到影响?(所有用户?仅移动设备用户?网络连接缓慢的用户?)
重要:优化前后都要测量。过早优化会浪费时间。应优化真正重要的部分。
优化策略
制定系统性的改进计划:
加载性能
优化图像:
- 使用现代格式(WebP、AVIF)
- 调整合适的尺寸(不要为 300px 的显示区域加载 3000px 的图像)
- 对首屏以下的图像进行延迟加载
- 使用响应式图像(
srcset、picture元素) - 压缩图像(通常 80-85% 的质量损失难以察觉)
- 使用 CDN 加快交付速度
<img
src="hero.webp"
srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
sizes="(max-width: 400px) 400px, (max-width: 800px) 800px, 1200px"
loading="lazy"
alt="Hero image"
/>
减小 JavaScript 包体积:
- 代码拆分(按路由、按组件)
- 摇树优化(移除未使用的代码)
- 移除未使用的依赖项
- 延迟加载非关键代码
- 对大型组件使用动态导入
// Lazy load heavy component
const HeavyChart = lazy(() => import('./HeavyChart'));
优化 CSS:
- 移除未使用的 CSS
- 将关键 CSS 内联,其余部分异步加载
- 精简 CSS 文件
- 使用 CSS containment 隔离独立区域
优化字体:
- 使用
font-display: swap或optional - 对字体进行子集化(仅包含所需字符)
- 预加载关键字体
- 适当时使用系统字体
- 限制加载的字体粗细
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: swap; /* Show fallback immediately */
unicode-range: U+0020-007F; /* Basic Latin only */
}
优化加载策略:
- 优先加载关键资源(对非关键资源使用 async/defer)
- 预加载关键资源
- 预获取可能访问的下一页面
- 使用 Service Worker 实现离线访问和缓存
- 使用 HTTP/2 或 HTTP/3 实现多路复用
渲染性能
避免布局抖动:
// ❌ Bad: Alternating reads and writes (causes reflows)
elements.forEach(el => {
const height = el.offsetHeight; // Read (forces layout)
el.style.height = height * 2; // Write
});
// ✅ Good: Batch reads, then batch writes
const heights = elements.map(el => el.offsetHeight); // All reads
elements.forEach((el, i) => {
el.style.height = heights[i] * 2; // All writes
});
优化渲染:
- 使用 CSS
contain属性隔离独立区域 - 减少 DOM 深度(结构越扁平,速度越快)
- 缩减 DOM 大小(减少元素数量)
- 对长列表使用
content-visibility: auto - 对超长列表使用虚拟滚动(react-window、react-virtualized)
减少绘制和合成:
- 使用
transform和opacity创建动画(由 GPU 加速) - 避免为布局属性添加动画(width、height、top、left)
- 仅在已知开销较大的操作中谨慎使用
will-change - 缩小绘制区域(区域越小,速度越快)
动画性能
GPU 加速:
/* ✅ GPU-accelerated (fast) */
.animated {
transform: translateX(100px);
opacity: 0.5;
}
/* ❌ CPU-bound (slow) */
.animated {
left: 100px;
width: 300px;
}
流畅达到 60fps:
- 将每帧耗时控制在 16ms(60fps)
- 使用
requestAnimationFrame实现 JavaScript 动画 - 对滚动处理器进行防抖/节流
- 尽可能使用 CSS 动画
- 避免在动画期间运行耗时较长的 JavaScript
Intersection Observer:
// Efficiently detect when elements enter viewport
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// Element is visible, lazy load or animate
}
});
});
React/框架优化
React 特定优化:
- 对开销较大的组件使用
memo() - 对开销较大的计算使用
useMemo()和useCallback() - 对长列表进行虚拟化
- 对路由进行代码拆分
- 避免在渲染过程中内联创建函数
- 使用 React DevTools Profiler
适用于所有框架的优化:
- 尽量减少重新渲染
- 对开销较大的操作进行防抖
- 对计算结果进行记忆化
- 延迟加载路由和组件
网络优化
减少请求:
- 合并小文件
- 使用 SVG 雪碧图显示图标
- 将小型关键资源内联
- 移除未使用的第三方脚本
优化 API:
- 使用分页(不要一次性加载所有内容)
- 使用 GraphQL 仅请求所需字段
- 压缩响应(gzip、brotli)
- 设置 HTTP 缓存标头
- 使用 CDN 加速静态资源
针对慢速连接进行优化:
- 根据连接状态自适应加载(navigator.connection)
- 使用乐观 UI 更新
- 对请求进行优先级排序
- 渐进增强
Core Web Vitals 优化
最大内容绘制(LCP < 2.5s)
- 优化主视觉图片
- 内联关键 CSS
- 预加载关键资源
- 使用 CDN
- 服务端渲染
首次输入延迟(FID < 100ms)/ INP(< 200ms)
- 拆分长任务
- 延迟加载非关键 JavaScript
- 使用 Web Worker 处理繁重计算
- 缩短 JavaScript 执行时间
累积布局偏移(CLS < 0.1)
- 设置图片和视频的尺寸
- 不要在现有内容上方插入内容
- 使用
aspect-ratioCSS 属性 - 为广告和嵌入内容预留空间
- 避免导致布局偏移的动画
/* Reserve space for image */
.image-container {
aspect-ratio: 16 / 9;
}
性能监控
可使用的工具:
- Chrome DevTools(Lighthouse、Performance 面板)
- WebPageTest
- Core Web Vitals(Chrome UX Report)
- 包分析工具(webpack-bundle-analyzer)
- 性能监控工具(Sentry、DataDog、New Relic)
关键指标:
- LCP、FID/INP、CLS(Core Web Vitals)
- 可交互时间(TTI)
- 首次内容绘制(FCP)
- 总阻塞时间(TBT)
- 包大小
- 请求数
重要:在真实设备和真实网络条件下进行测量。使用快速网络连接的桌面版 Chrome 并不能代表实际情况。
绝不要:
- 不经测量就进行优化(过早优化)
- 为了性能牺牲无障碍性
- 在优化时破坏功能
- 到处使用
will-change(这会创建新图层并占用内存) - 对首屏内容进行延迟加载
- 忽视重大问题、只优化微小细节(优先优化最大的瓶颈)
- 忽视移动端性能(设备通常较慢,网络连接也较慢)
验证改进效果
测试优化是否有效:
- 优化前后指标:比较 Lighthouse 评分
- 真实用户监控:跟踪真实用户的体验改进
- 不同设备:在低端 Android 设备上测试,而不只是旗舰 iPhone
- 慢速网络连接:限速至 3G,测试使用体验
- 无回归问题:确保功能仍然正常
- 用户感知:使用体验感觉更快了吗?
请记住:性能是一项功能。快速的体验会让人感觉响应更灵敏、更精致、更专业。系统地进行优化,严格地进行测量,并优先改善用户感知到的性能。
评论
支持 Markdown