一、加载性能优化
1. 减少资源体积
- 代码压缩(Minify) :压缩 HTML / CSS / JS,移除空白、注释
- Tree Shaking:利用 ES Module 静态分析,打包时剔除未使用的代码
- 代码分割(Code Splitting) :按路由或组件懒加载,避免首屏加载过多代码
- 图片压缩:使用 WebP / AVIF 格式,配合工具(imagemin、Squoosh)压缩
- 开启 Gzip / Brotli:服务端开启压缩,传输体积可减少 60%~80%
2. 减少请求数量
- 合并请求:将小图标合成 CSS Sprite 或使用 SVG Sprite
- 内联关键资源:关键 CSS / 小图片用 base64 内联,减少请求往返
- 使用字体图标 / SVG:替代大量小图片
3. 缓存策略
- 强缓存:
Cache-Control: max-age=31536000,资源文件名加 hash,永久缓存 - 协商缓存:
ETag/Last-Modified,资源未变则返回 304 - Service Worker:离线缓存,实现 PWA,二次访问直接走本地缓存
- CDN:静态资源上 CDN,利用边缘节点就近访问
4. 资源加载优先级
- 预加载(Preload) :
<link rel="preload">提前加载关键资源(字体、首屏图片) - 预获取(Prefetch) :
<link rel="prefetch">提前获取下一页资源 - DNS 预解析:
<link rel="dns-prefetch">提前解析第三方域名 - 预连接(Preconnect) :
<link rel="preconnect">提前建立 TCP 连接
二、渲染性能优化
1. 关键渲染路径优化
-
CSS 放
<head>:避免 FOUC(无样式内容闪烁) -
JS 放底部 / 使用 defer 或 async:避免阻塞 HTML 解析
defer:并行下载,HTML 解析完后按序执行async:并行下载,下载完立即执行(顺序不保证)
-
减少关键 CSS 体积:内联首屏必要的 Critical CSS
2. 减少重排(Reflow)与重绘(Repaint)
- 批量 DOM 操作:使用
DocumentFragment或一次性修改,避免多次触发回流 - 避免强制同步布局:不要在循环中读写布局属性(
offsetWidth、getBoundingClientRect) - 使用 CSS 动画代替 JS 动画:CSS transform / opacity 在合成层执行,不触发回流
- will-change 提示:
will-change: transform提前创建合成层(慎用,有内存开销)
3. 长列表优化
- 虚拟滚动(Virtual Scroll) :只渲染可视区域的 DOM 节点,如
vue-virtual-scroller、react-window - 分页 / 无限滚动:按需加载数据,避免一次渲染大量节点
4. 图片与媒体
- 懒加载(Lazy Load) :
loading="lazy"或 IntersectionObserver - 响应式图片:
<picture>+srcset,根据设备像素比和视口大小加载合适图片 - 占位符(Skeleton / Blur-up) :先展示低质量占位图,改善感知性能
三、JavaScript 执行优化
1. 减少主线程压力
- Web Worker:将计算密集型任务(数据处理、加密)移到 Worker 线程
- 时间分片(Time Slicing) :用
requestIdleCallback或setTimeout拆分长任务,避免阻塞主线程超过 50ms
2. 节流与防抖
- 防抖(Debounce) :连续触发只执行最后一次,适合搜索输入
- 节流(Throttle) :限制执行频率,适合 scroll / resize 事件
3. 避免内存泄漏
- 及时清除定时器、事件监听
- 使用
WeakMap/WeakRef避免意外引用阻止 GC - 组件卸载时取消异步请求和订阅
四、网络层优化
1. HTTP 协议升级
- HTTP/2:多路复用,头部压缩,消除队头阻塞,告别 HTTP/1.1 的 6 个并发限制
- HTTP/3 (QUIC) :基于 UDP,减少握手延迟,弱网环境更稳定
2. 接口优化
- 接口合并 / BFF:减少前端多次请求,后端聚合数据
- GraphQL:按需获取字段,避免 over-fetching
- 数据缓存:客户端缓存接口数据(SWR、React Query),减少重复请求
- SSR / SSG:服务端渲染或静态生成,减少首屏白屏时间
五、构建与工程优化
| 优化手段 | 说明 |
|---|---|
| 按需引入组件库 | 使用 babel-plugin-import 或自动按需引入,避免全量打包 |
| 分析打包产物 | webpack-bundle-analyzer / rollup-plugin-visualizer 找出体积大头 |
| 持久化缓存 | Webpack 5 cache: { type: 'filesystem' },加速二次构建 |
| Vite 替代 Webpack | 基于 ESM 的开发服务器,HMR 极速,开发体验大幅提升 |
| 公共依赖外链 | React / Vue 等通过 externals 走 CDN,不打入 bundle |
| 模块联邦(Module Federation) | 微前端场景下跨应用共享模块,避免重复打包 |
六、感知性能优化
实际速度有限时,优化用户「感觉上」的快
- 骨架屏(Skeleton Screen) :占位替代空白等待
- 乐观更新(Optimistic UI) :操作立即反馈,后台异步同步
- 渐进式加载:先展示核心内容,次要内容延迟加载
- 进度条 / Loading 动画:给用户明确的等待反馈(如 NProgress)
- 预测性预加载:鼠标 hover 链接时提前 prefetch 对应页面
七、性能指标(Core Web Vitals)
| 指标 | 全称 | 含义 | 优秀阈值 |
|---|---|---|---|
| LCP | Largest Contentful Paint | 最大内容渲染时间 | ≤ 2.5s |
| FID | First Input Delay | 首次输入延迟 | ≤ 100ms |
| CLS | Cumulative Layout Shift | 累积布局偏移 | ≤ 0.1 |
| INP | Interaction to Next Paint | 交互到下一帧绘制(替代 FID) | ≤ 200ms |
| FCP | First Contentful Paint | 首次内容渲染 | ≤ 1.8s |
| TTFB | Time to First Byte | 首字节到达时间 | ≤ 800ms |
常用测量工具
- Lighthouse:Chrome DevTools 内置,综合评分
- WebPageTest:多地点、多网络条件测试
- Chrome Performance 面板:录制运行时性能,分析帧率与长任务
- web-vitals 库:生产环境埋点采集真实用户数据
八、优先级建议
高优先级(投入产出比高)
├── 开启 Gzip/Brotli 压缩
├── 静态资源上 CDN + 强缓存
├── 图片懒加载 + WebP 格式
├── JS defer/async + 代码分割
└── 关键 CSS 内联
中优先级
├── 虚拟滚动(长列表场景)
├── 防抖节流
├── Service Worker 缓存
└── HTTP/2 升级
低优先级(细节打磨)
├── will-change 合成层优化
├── Web Worker 密集计算
└── 骨架屏 / 乐观更新
最后:性能优化是持续的过程,先度量,再优化,避免过早优化。