我的文档库

性能优化

从网络、浏览器渲染、JavaScript 到 Core Web Vitals,建立完整的前端性能分析体系

用户到底慢在哪里?

一个页面慢,可能来自:

DNS
TCP
TLS
HTTP
Server
HTML
CSS
JS
Font
Image
Layout
Paint
Hydration
Interaction

因此性能优化首先是一门:

测量学。


1. 浏览器打开页面发生了什么?

可以粗略表示为:

URL
 ↓
DNS
 ↓
TCP
 ↓
TLS
 ↓
HTTP
 ↓
Server
 ↓
HTML
 ↓
Parse
 ↓
CSSOM
 ↓
DOM
 ↓
Render Tree
 ↓
Layout
 ↓
Paint
 ↓
Composite

现代页面还会穿插:

JavaScript
Font
Image
Hydration
Async Data

2. TTFB 到底是什么?

TTFB:

Time To First Byte

可以粗略理解:

Request
 ↓
DNS
 ↓
Connect
 ↓
TLS
 ↓
Server Processing
 ↓
First Byte

因此:

TTFB 高不一定是服务器 CPU 慢。

可能是:

  • DNS
  • 连接建立
  • TLS
  • CDN
  • Worker
  • Origin
  • Database

任何一个环节都可能影响它。


3. 为什么平均值不够?

假设:

平均 TTFB = 200ms

看起来不错。

但:

p50 = 100ms
p90 = 300ms
p95 = 800ms
p99 = 3000ms

说明:

大部分用户很快,但尾部用户非常慢。

线上性能更应该关注:

p50
p75
p90
p95
p99

以及:

不同地区
不同设备
不同网络
不同页面

4. Core Web Vitals

现代 Web 性能最重要的用户体验指标之一包括:

LCP
INP
CLS

可以分别理解:

LCP
↓
主要内容什么时候出现

INP
↓
用户操作响应是否及时

CLS
↓
页面是否发生意外布局移动

所以:

性能

并不只是:

加载速度

还包括:

交互
稳定性

5. LCP 为什么经常优化错?

假设 LCP 元素是:

<img src="/hero.webp" />

很多人只会:

压缩图片

但真正的问题可能是:

HTML 到得太晚
 ↓
图片请求启动太晚

或者:

图片虽然很小
 ↓
优先级太低

所以分析 LCP 必须拆成:

TTFB
+
Resource Load Delay
+
Resource Load Duration
+
Element Render Delay

6. INP

INP 关注:

用户操作
 ↓
事件处理
 ↓
下一次视觉更新

例如:

Click
 ↓
大量 JS
 ↓
React Render
 ↓
Layout
 ↓
Paint

如果主线程被长任务阻塞:

Click
        ↓
████████████████
Long Task
        ↓
UI Response

用户就会感觉:

“点了没反应。”


7. Long Task

浏览器主线程上的长时间 JavaScript 执行会影响:

Input
Rendering
Animation

常见来源:

  • 大型 JSON Parse
  • 复杂 React Render
  • 第三方 SDK
  • 大 Bundle
  • 同步计算

所以性能分析不能只看:

Bundle Size

还需要看:

Main Thread Time

8. CLS 为什么发生?

例如:

<img src="banner.jpg">

图片没有提前确定尺寸:

初始:

Text
Text
Text

图片加载后:

Image
Image
Text
Text

页面发生移动。

解决方案之一:

<img
  width="1200"
  height="600"
/>

让浏览器提前知道布局尺寸。


9. Cache 设计

前端缓存通常包括:

Browser Cache
Service Worker Cache
CDN Cache
Application Cache
Database Cache

例如静态资源:

/app.a8f31.js

可以:

Cache-Control: public, max-age=31536000, immutable

因为:

文件名变化
=
内容变化

10. HTML 和静态资源的缓存策略应该不同

通常:

HTML
↓
短缓存 / revalidate

JS/CSS
↓
长缓存

Hash Asset
↓
immutable

原因是:

HTML

负责告诉浏览器:

当前页面应该加载哪些资源。

而:

app.a8f31.js

本身可以长期缓存。


11. 性能优化的一个核心思想

不要优化:

资源

而要优化:

关键路径

例如:

HTML
 ↓
Critical CSS
 ↓
LCP Image
 ↓
Visible UI

应该优先。

而:

页面底部组件
分析 SDK
非首屏图片

可以延迟。


12. RUM 比 Lighthouse 更重要

Lighthouse:

Synthetic

它是在:

固定环境

测试。

RUM:

Real User Monitoring

是真实用户数据。

例如:

Chrome
Safari
iPhone
Android
4G
5G
WiFi
美国
欧洲
亚洲

真实用户数据才能告诉你:

用户到底遇到了什么。


13. 前端性能监控应该记录什么?

建议至少:

  • URL
  • Navigation Type
  • Device
  • Browser
  • Country
  • Connection
  • LCP
  • INP
  • CLS
  • TTFB
  • FCP
  • Resource Timing
  • Long Task
  • JS Error
  • Chunk Error

进一步可以:

Release
 ↓
Page
 ↓
Performance
 ↓
Error

建立版本维度分析。


14. 性能问题排查模型

遇到:

“首页很慢。”

不要直接:

优化代码

应该:

1. 慢在哪里?
2. 哪个阶段慢?
3. 哪类用户慢?
4. 哪个版本开始慢?
5. 是否所有用户都慢?
6. 是网络还是服务器?
7. 是资源还是渲染?
8. 是偶发还是持续?

最终建立:

Metric
 ↓
Dimension
 ↓
Outlier
 ↓
Root Cause
 ↓
Optimization
 ↓
Regression Monitoring

本页目录