TL;DR(拿去即用的清单)
- 以 Core Web Vitals 与 TTFB 为第一目标:LCP ≤ 2.5s、CLS ≤ 0.1、INP ≤ 200ms、TTFB ≤ 800ms(上限 1.3s)。
- 建立 性能预算(Performance Budget) 与 CI 守护:Lighthouse CI + Bundle 分析 + RUM 监控。
- 网络层先行:CDN + Brotli 压缩 + 长缓存(immutable)+ 预连接(preconnect)。
- 关键渲染路径最小化:内联 Critical CSS、非阻塞 CSS/JS、按需加载与拆包。
- 图片 & 字体是大头:WebP/AVIF、响应式
srcset/sizes
、loading="lazy"
、字体子集 +font-display: swap
。 - 第三方与 Iframe 严监管:能不引就不引;必须引就延迟、隔离、降权。
- 运行时流畅度:
content-visibility: auto
、虚拟列表、Web Worker、节流防抖、避免强制同步布局。
为什么是“指标驱动”而不是“感觉优化”?
真正的性能优化应当 可度量、可回归、可回放。建议以以下指标闭环:
-
Core Web Vitals:
- LCP(最大内容绘制):≤ 2.5s
- CLS(累计布局偏移):≤ 0.1
- INP(交互到下一次绘制):≤ 200ms
-
TTFB(首字节时间):推荐 ≤ 800ms,保底 ≤ 1.3s。
-
页面体积预算:理想 ≤ 500KB,最大 ≤ 1500KB(含首屏关键资源)。
建议同时部署 合成监控(Lighthouse、WebPageTest)与 真实用户监控(RUM),以覆盖不同网络、设备、地区场景。
网络与服务端:把“慢”挡在前端之外
1) 缓存与 CDN
-
静态资源使用 指纹文件名(content hash),并下发:
Cache-Control: public, max-age=31536000, immutable
-
页面 HTML 使用短缓存或禁缓存,结合服务端/边缘缓存(CDN、边缘计算/Edge)。
-
跨地域建议启用多 CDN 或智能调度,降低 RTT。
2) 传输与压缩
- 全站开启 Brotli(优先于 Gzip),文本资源(HTML/CSS/JS/JSON/SVG)全量压缩。
- HTTP/2/3 默认开启;HTTP/2 Push 已过时,请用
<link rel="preload">
替代。
3) 连接与优先级
<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<link rel="preload" as="style" href="/assets/critical.css" onload="this.rel='stylesheet'">
<link rel="preload" as="image" href="/hero.avif" imagesrcset="/hero.avif 1x, /hero@2x.avif 2x" fetchpriority="high">
4) TTFB 优化(≤ 800ms 为佳)
- SSR/SSG/ISR 或边缘渲染,减少服务端计算与数据库查询。
- 启用应用级/查询级缓存(Redis)、减少 N+1 查询、延迟加载非关键数据。
- 流式输出(React 18 Streaming/Suspense、Node/Edge streaming)。
CSS:关键渲染路径最短,非必要都让路
1) 非阻塞加载
<link rel="preload" href="/styles.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/styles.css"></noscript>
2) 内联 Critical CSS
- 将 首屏必需样式 内联到
<head>
的<style>
中。 - 使用工具链自动提取(如 critical/critters、LightningCSS 集成)。
3) 降低样式复杂度
- 移除冗余/未使用样式(PurgeCSS、LightningCSS、Stylelint)。
- 控制选择器深度与通配符使用,减少重排重绘成本。
- 避免在
<body>
中随意写内联样式,统一走外链样式管理(关键样式内联除外)。
4) 新特性加速首屏
/* 首屏块级内容懒渲染:非可视区域先跳过布局与绘制 */
.card-grid {
content-visibility: auto;
contain-intrinsic-size: 600px 800px;
}
JavaScript:更少、更晚、更快
1) 加载策略
<script type="module" src="/main.js"></script> <!-- 原生模块默认 defer -->
<script nomodule src="/legacy.bundle.js"></script> <!-- 老浏览器兜底 -->
<script defer src="/critical-first.js"></script>
- 第三方脚本尽量
async
/defer
,必要时延迟到首屏稳定后加载。
2) 体积治理
- 按路由/组件拆包(Code Splitting),使用
import()
懒加载。 - Tree Shaking:只打入用到的导出;避免通配符引入。
- 优选编译器/打包器:Vite + esbuild/SWC、Rollup、LightningCSS。
- 使用 Bundle 分析(
rollup-plugin-visualizer
、webpack-bundle-analyzer
)。
3) 运行时流畅度
- 避免长任务(> 50ms),使用 Web Worker/OffscreenCanvas 迁移重计算与绘制。
- 在事件层使用节流/防抖(
scroll
/resize
/mousemove
)。 - 合理使用
requestIdleCallback
执行非关键任务。
图片与媒体:先做这块,KPI 往往直接见效
1) 选择合适格式
- 位图优先 AVIF/WebP;图标与矢量优先 SVG。
- GIF 动画用 video 或 Lottie 代替。
2) 响应式与惰性加载
<img
src="/hero.avif"
srcset="/hero.avif 1x, /hero@2x.avif 2x"
sizes="(max-width: 768px) 100vw, 50vw"
width="1200" height="800"
loading="lazy" decoding="async" fetchpriority="high" />
3) 压缩与处理
- 目标质量 ≈ 80–85%,按视觉效果回归。
- 通过 CI/CD 或图床(如自建服务/云存储)自动化压缩与裁剪。
字体优化:小改动,大收益
@font-face {
font-family: 'InterSubset';
src: url('/fonts/inter-subset.woff2') format('woff2');
font-display: swap; /* 避免文字不可见 */
unicode-range: U+0020-007F, U+4E00-9FFF; /* 子集化 */
}
- 使用 可变字体 或 子集化(拉丁/中日韩拆分),减少下载体积。
- 仅在必要时加载品牌字体;系统字体栈能满足就不引第三方。
布局与渲染:避免“抖、卡、跳”
- 预留媒体尺寸(
width/height
或 CSSaspect-ratio
),降低 CLS。 - 谨慎使用
will-change
,只在短时动画前设置并及时移除。 - 避免读写混用触发布局抖动(样式读写分离)。
- 减少重排热点:使用 CSS Containment(
contain
)。
第三方脚本治理:少即是多
- 严格盘点:广告、统计、热图、客服、A/B 等是否都必要?
- 降影响策略:
async
/defer
、延迟注入、同源代理、sandbox iframe 隔离。 - 统一从 单一入口 引入与配置,便于开关与灰度。
Iframe:尽量不用;必须用就把影响降到最低
替代优先:能用 API/Embed SDK/组件方式对接就不用 Iframe。
必须使用时的最佳实践:
<iframe
src="https://third.example.com/embed"
loading="lazy"
width="800" height="600" title="Third Party Widget"
sandbox="allow-scripts allow-same-origin"
referrerpolicy="no-referrer"
></iframe>
- 提供固定尺寸或占位,避免 CLS。
- 使用
loading="lazy"
懒加载;sandbox
权限最小化;必要时加allow
白名单。 - 与业务解耦:提供降级与失败兜底文案/骨架屏。
工程化治理:把“偶尔优化”变成“持续优化”
- 性能预算(体积/请求数/LCP/INP/TTFB 等)固化到仓库。
- CI 守护:Lighthouse CI + Bundle Analyzer,红线直接失败。
- 监控告警:接入 RUM(真实用户监控),分网络/设备/地域看分布。
- 回归基准:关键页面与交互建立自动化性能基线。
常见误区(避坑)
- 只做一次“突击优化”,没有预算与监控,回弹极快。
- 认为“SSR 一定更快”:服务端慢/网络差/水合开销大都会拖后腿。
- 无脑引入组件库与 polyfill:按需加载与按环境下发才是正解。
- 滥用动画、阴影、毛玻璃等高成本效果,导致中低端机掉帧。
工具速查
- 分析:Chrome DevTools(Performance/Coverage)、Lighthouse、WebPageTest。
- 构建:Vite、Rollup、esbuild/SWC、LightningCSS、Terser。
- 监控:Lighthouse CI、SpeedCurve/Calibre(可选)、自建 RUM。
- 图片/字体:Squoosh、Sharp、FontTools/pyftsubset。
关于页面体积与加载时间的建议线
- 理想页面体积 ≤ 500KB,可接受上限 ≤ 1500KB(含首屏关键资源)。
- 移动端 3s 内首屏渲染完成 是基础目标,核心交互 INP ≤ 200ms。
- 达不到时先从图片与第三方脚本下手,收效最高。
总结
前端性能优化不是“堆技巧”,而是 基于指标的长期工程:
- 先量化(CWV/TTFB/预算)
- 再优化(网络 → 渲染 → 运行时)
- 最后守护(CI/监控/告警)