Roger Leung‘s Epcot

vuePress-theme-reco Roger Leung ( z3rog )    2018 - 2021
Roger Leung‘s Epcot

Choose mode

  • dark
  • auto
  • light
Blog
Note
Github (opens new window)
author-avatar

Roger Leung ( z3rog )

18

Article

20

Tag

Blog
Note
Github (opens new window)
  • 首页
  • 框架与工具链

    • Vue 3
    • Vue 2
    • Webpack 4
  • 前端性能优化

    • 性能优化的必要性
    • 性能指标
    • 基本手段
    • 离线缓存
  • 浏览器机制

    • 架构
    • 导航
    • 渲染机制
    • 缓存机制
  • 网络协议

    • TCP 协议
    • HTTP 协议
    • HTTPS 协议
    • HTTP 2 协议
    • HTTP 3 协议
  • 其他

    • V8 中的快慢属性与快慢数组
    • V8 解析执行 JavaScript 流程简述
    • V8 的垃圾回收机制
    • 100 行代码写一个破产版 Vite
    • 浅谈微前端

性能指标

vuePress-theme-reco Roger Leung ( z3rog )    2018 - 2021

性能指标

Roger Leung ( z3rog ) 2020-02-20 Chrome

浅谈前端性能指标

在 浏览器导航 中介绍过,通过 performance.timing 我们可以访问到一些列性能指标,且这些指标精确到纳秒级别,对我们进行性能优化是很有参考意义的。显然,这些指标中绝大多数都属于非视觉指标(Non-Visual Metrics),相反与用户体验密切度更高、更视觉化的一些「时机」是视觉指标。

# 非视觉指标

非视觉指标的计算依赖于 performance.timing API:

const {
  navigationStart,
  redirectStart,
  redirectEnd,
  fetchStart,
  // ...此处省略
} = performance.timing

下面说明根据这些属性可以直接计算出什么指标。
1
2
3
4
5
6
7
8
9

各值的含义见 浏览器导航,你可以选择直接阅读 W3C (opens new window)

# 重定向时间

const redirectTime = redirectEnd - redirectStart
1

# DNS 解析时间

const dnsTime = domainLookupEnd - domainLookupStart
1

# 首字节时间

const ttfbTime = responseStart - navigationStart
1

# TCP 连接时间

const tcpTime = connectEnd - connectStart
1

# 请求时间

const requestTime = responseEnd - responseStart
1

# DOM 树解析时间

const domParseTime = domComplete - domLoading
1

# DOM ready 时间


const domReadyTime = domContentLoadedEventEnd - fetchStart
1
2

# 页面卸载时间

const unloadTime = unloadEventEnd - unloadEventStart
1

# 非视觉指标的局限性

当前 SPA 盛行,基于 Vue、 React 的 Web App 层出不穷,但因为这些框架对页面内容渲染时机的改变,上述公式计算出的性能指标并不能正确反应真实的页面渲染性能了。并且,SPA 应用的假路由实现页面切换时,performance.timing API 是不会更新的,这种情况下要实现性能监控,只能够自定义上报。

# 视觉指标

以下指标与用户视觉体验上的感知密切度更高,因而归类为视觉指标。最后说说部分指标如何计算。

# 首次绘制时间

首次渲染(First Paint,又成为 First Non-Blank Paint),表示文档中任意元素首次渲染的时间。

# 首次内容绘制时间

First Contentful Paint 代表文档中内容元素(文本、图像、Canvas,或者 SVG)首次渲染的时间。它通常情况下是无意义的渲染,比如头部和导航条。

# 首次有意义绘制时间

首次有意义渲染(First Meaningful Paint),代表首次有意义的渲染时间,它的统计在重大的布局变化之后,往往代表了用户所关心的首次渲染时间)。

# 首次可交互时间

首次可交互(First Interactive)

# 持续可交互时间

持续可交互(Consistently Interactive)。

# 指标计算

# 计算 FP、FCP

可以参考 codepen (opens new window) 这个例子,并尝试为 body 增加一个背景色或为 body 中的 div 增加内容。你可以发现:

  • 当 body 没有背景色,div 中也没有内容时,不会触发任何绘制
  • 当 body 有背景色,div 没有内容时,只会触发 FP
  • 当 div 有内容时,不管 body 是否有颜色,都会触发 FP、FCP

核心的 JS 代码如下:

const observer = new PerformanceObserver(list => {
  for (const entry of list.getEntries()) {
    const { entryType, name, startTime, duration } = entry
      console.log('类型', entryType)
      console.log('具体指标', name)
      console.log('开始时间', startTime)
      console.log('duration', duration)
    }
  })

observer.observe({ entryTypes: ['paint']})
1
2
3
4
5
6
7
8
9
10
11

# 计算 FMP

下面这个例子(见 codepen (opens new window))计算的是文字渲染出的时间,但由于 FMP 字面意思中各人对「有意义」的定义并不一致,因此实际统计 FMP,需要手动对某个认为有意义的元素进行标记,才能统计出对应元素的绘制时间。

performance.mark('text')

const performanceEntries = performance.getEntriesByType('mark')

for (const entry of performanceEntries) {
  const { entryType, name, startTime, duration } = entry

  console.log('entry', entry)
  console.log('类型', entryType)
  console.log('具体指标', name)
  console.log('开始时间', startTime)
  console.log('duration', duration);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14

推荐阅读:网站性能指标 - FMP (opens new window) 及 前端性能监控(一)指标收集 (opens new window) 的 FMP 部分