Web性能指标

Web性能指标模型

一、RAIL 模型

RAILResponseAnimationIdleLoad 的首字母缩写,是一种由 Google Chrome 团队于 2015 年提出的性能模型,用于提升浏览器内的用户体验和性能。

RAIL 模型.png
  • Response(响应):在 \color{red}{50ms}内处理事件
    目标:在 100 ms内完成由用户输入发起的转换,让用户感觉交互是即时的。
    响应.png
  • Animatio(动画): 在 \color{red}{10 ms}内生成一帧,目的为流畅的视觉效果
    在 10 毫秒或更短的时间内生成动画的每一帧。从技术上来讲,每帧的最大预算为 16 ms(1000 ms/每秒 60 帧≈16 ms),但是,浏览器需要大约 6 ms速来渲染一帧,因此,准则为每帧 10ms。
  • Idle(空闲):最大限度增加空闲时间
    最大限度增加空闲时间以提高页面在 50 ms内响应用户输入的几率
  • Load(加载):在5s内交付并实现可交互
    目前,对于\color{red}{首次加载},在使用速度较慢 3G 连接的中端移动设备上,理想的目标是在 \color{red}{5s}或更短的事件内实现交互
    对于后续加载,理想的目标是在 \color{red}{2s}内加载页面。

二、基于用户体验的性能指标

基于用户体验的核心指标 是 Google 在 web.dev 提出的

1. FCP (First Contentful Paint, 首次内容绘制)

含义

首次内容绘制 (FCP) 指标测量页面从开始加载到页面内容的任何部分在屏幕上完成渲染的时间。对于该指标,"内容"指的是文本、图像(包括背景图像)、<svg>元素或非白色的<canvas>元素。

FCP.png

指标

FCP指标.png

测量方式

  • web-vitals
import {getFCP} from 'web-vitals';

// 当 FCP 可用时立即进行测量和记录。
getFCP(console.log);
  • lighthouse
  • chrome 开发者工具

优化方案

2. LCP (Largest Contentful Paint, 最大内容绘制)

含义

最大内容绘制 (LCP) 指标会根据页面首次开始加载的时间点来报告可视区域内可见的最大图像或文本块完成渲染的相对时间。

LCP.png

指标

LCP指标.png

测量方法

import {getLCP} from 'web-vitals';

// 当 LCP 可用时立即进行测量和记录。
getLCP(console.log);

影响因素

  • 的服务器响应速度
  • JavaScript 和 CSS 渲染阻塞
  • 资源加载时间
  • 客户端渲染

优化方案

3. FID (First Input Delay,首次输入延迟)

含义

FID 测量从用户第一次与页面交互(例如当他们单击链接、点按按钮或使用由 JavaScript 驱动的自定义控件)直到浏览器对交互作出响应,并实际能够开始处理事件处理程序所经过的时间。


FID交互时间点.png
  • 上方的可视化图表中显示的是一个页面,该页面正在发出数个网络请求来获取资源(多为 CSS 和 JS 文件),这些资源下载完毕后,会在主线程上进行处理。这就导致主线程会阶段性地处于忙碌状态(在图中表示为米黄色任务块)
  • 较长的首次输入延迟通常发生在首次内容绘制 (FCP)Time to Interactive 可交互时间 (TTI)之间,因为在此期间,页面已经渲染出部分内容,但交互性还尚不可靠。
  • 如果用户在最长的任务刚开始时就尝试与页面进行交互,因为输入发生在浏览器正在运行任务的过程中,所以浏览器必须等到任务完成后才能对输入作出响应。浏览器必须等待的这段时间就是这位用户在该页面上体验到的 FID 值。

指标

FID指标.png

测量方法

import {getFID} from 'web-vitals';

// 当 FID 可用时立即进行测量和记录。
getFID(console.log);

优化方案

4. TTI (Time to Interactive, 可交互时间)

含义

TTI 指标测量页面从开始加载到主要子资源完成渲染,并能够快速、可靠地响应用户输入所需的时间


TTI.png
  • ① 先进行First Contentful Paint 首次内容绘制 (FCP)
  • ② 沿时间轴正向搜索时长至少为 5 秒的安静窗口,其中,安静窗口的定义为:没有长任务且不超过两个正在处理的网络 GET 请求。
  • ③ 沿时间轴反向搜索安静窗口之前的最后一个长任务,如果没有找到长任务,则在 FCP 步骤停止执行。
  • ④ TTI 是安静窗口之前最后一个长任务的结束时间(如果没有找到长任务,则与 FCP 值相同)。

指标

TTI指标(单位:秒) 颜色编码
0-3.8 绿色(快速)
3.9-7.3 橙色(中等)
>7.3 红色(慢)

优化方案

5. TBT (Total Blocking Time, 总阻塞时间)

含义

总阻塞时间 (TBT) 指标测量First Contentful Paint 首次内容绘制 (FCP)Time to Interactive 可交互时间 (TTI)之间的总时间,这期间,主线程被阻塞的时间过长,无法作出输入响应。

各任务消耗时间.png

长任务:在主线程上运行超过 50 ms的任务。

各长任务阻塞时间.png

虽然在主线程上运行任务的总时间为 560(250+90+35+30+155 = 560) 毫秒,但其中只有 345(200+40+105 = 345) 毫秒被视为阻塞时间

指标

TBT指标(单位:毫秒) 颜色编码
0-200 绿色(快速)
200-600 橙色(中等)
>600 红色(慢)

优化方案

6. CLS (Cumulative layout shift, 累计布局偏移)

含义

测量页面在开始加载和其生命周期状态变为隐藏期间发生的所有意外布局偏移的累积分数。
每当一个可见元素的位置从一个已渲染帧变更到下一个已渲染帧时,就发生了布局偏移。

指标

CLS指标参数.png

布局偏移分数 = 影响分数 * 距离分数

布局偏移.png
  • 影响分数是0.75(红色虚线矩形框表示两帧中元素的可见区域集合,在本示例中,该集合占总可视区域的 75%,因此其影响分数为0.75 。)
  • 距离分数是0.25 (最大的可视区域尺寸维度是高度,不稳定元素的位移距离为可视区域高度的 25%,因此距离分数为 0.25)
  • 所以布局偏移分数是0.75 * 0.25 = 0.1875 。

测量方法

import {getCLS} from 'web-vitals';

// 在所有需要汇报 CLS 的情况下
// 对其进行测量和记录。
getCLS(console.log);

优化方案

  • 始终在您的图像和视频元素上包含尺寸属性,或者通过使用CSS 长宽比容器之类的方式预留所需的空间。
  • 除非是对用户交互做出响应,否则切勿在现有内容的上方插入内容。
  • 首选转换动画,而不是触发布局偏移的属性动画

7. SI

含义

指标

测量方法

优化方案

三、Web vitals

Web Vitals,即 Google 给的定义是一个良好网站的基本指标(Essential metrics for a healthy site)

web vitals.png

三大核心指标.png

Chorme network下Finish、DOMContentLoaded, Load参数含义

image.png
  • Finish: 页面上所有 http 请求发送到响应完成的时间。如果页面加载完后,触发了http请求,那么该时间会变更。
  • DOMContentLoaded:DOM 树构建完成。即 HTML 页面由上向下解析 HTML 结构到末尾的封闭标签·</html>。但像 <img> 和样式表之类的外部资源可能尚未加载完成。
  • Load:浏览器不仅加载完成了 HTML,还加载完成了所有外部资源:图片,样式等

Finish 与 DOMContentLoaded 和 Load 并无直接关系

DOMContentLoaded 触发时机

  • 无JS和CSS


    无JS和CSS.jpg
  • 只有CSS


    只有CSS.jpg
  • 有JS和CSS


    有JS和CSS.jpg

外部样式表不会影响 DOM,因此 DOMContentLoaded 不会等待它们。
但这里有一个陷阱。如果在样式后面有一个脚本,那么该脚本必须等待样式表加载完成:

<link type="text/css" rel="stylesheet" href="style.css">
<script>
  // 在样式表加载完成之前,脚本都不会执行
  alert(getComputedStyle(document.body).marginTop);
</script>
dom.png

首屏时间和白屏时间

白屏时间

白屏时间 = 地址栏输入网址后回车 - 浏览器出现\color{red}{第一个元素}
影响白屏时间的因素:网络,服务端性能,前端页面结构设计。
通常认为浏览器开始渲染 <body> 或者解析完 <head> 的时间是白屏结束的时间点。

首屏时间

首屏时间 = 地址栏输入网址后回车 - 浏览器\color{red}{第一屏渲染完成}
影响首屏时间的因素:白屏时间,资源下载执行时间。
关于首屏时间是否包含图片加载网上有不同的说法。

Performance Api

Navigation Timing Level 1

Navigation Timings involved as per the W3C spec-level1.png

performance.png
字段 含义
memory
jsHeapSizeLimit 上下文内可用堆的最大体积
totalJSHeapSize 已分配的堆体积
usedHeapSize 当前js堆活跃段的体积
navigation
redirectCount 重定向次数
type 如何导航至此页面:
0:点击链接,书签,表单提交,脚本操作,url中直接输入地址
1:点击刷新或者Location.reload()
2:浏览器历史记录,前进后退
255:其他方式
timing
connectEnd HTTP(TCP) 完成建立连接的时间(完成握手),如果是持久连接,则与 fetchStart 值相
注意如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接完成的时间
注意这里握手结束,包括安全连接建立完成、SOCKS 授权通过
connectStart HTTP(TCP) 开始建立连接的时间,如果是持久连接,则与 fetchStart 值相等
注意如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接开始的时间
domComplete DOM 树解析完成,且资源也准备就绪的时间,Document.readyState 变为 complete,并将抛出 readystatechange 相关事件
domContentLoadedEventEnd DOM 解析完成后,网页内资源加载完成的时间(如 JS 脚本加载执行完毕),触发DOMContentLoaded事件
domContentLoadedEventStart DOM 解析完成后,网页内资源加载开始的时间
在 DOMContentLoaded 事件抛出前发生
domInteractive 完成解析 DOM 树的时间,Document.readyState 变为 interactive,并将抛出 readystatechange 相关事件
注意只是 DOM 树解析完成,这时候并没有开始加载网页内的资源
domLoading 开始解析渲染 DOM 树的时间,此时 Document.readyState 变为 loading,并将抛出 readystatechange 相关事件
domainLookupEnd DNS 域名查询完成的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等
domainLookupStart DNS 域名查询开始的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等
fetchStart 浏览器准备好使用 HTTP 请求抓取文档的时间,这发生在检查本地缓存之前
loadEventEnd load 事件的回调函数执行完毕的时间
loadEventStart load 事件发送给文档,也即 load 回调函数开始执行的时间
注意如果没有绑定 load 事件,值为 0
navigationStart 在同一个浏览器上下文中,前一个网页(与当前页面不一定同域)unload 的时间戳,如果无前一个网页 unload ,则与 fetchStart 值相等
redirectEnd 最后一个 HTTP 重定向完成时的时间。有跳转且是同域名内部的重定向才算,否则值为 0
redirectStart 第一个 HTTP 重定向发生时的时间。有跳转且是同域名内的重定向才算,否则值为 0
requestStart HTTP 请求读取真实文档开始的时间(完成建立连接),包括从本地读取缓存
连接错误重连时,这里显示的也是新建立连接的时间
responseEnd HTTP 响应全部接收完成的时间(获取到最后一个字节),包括从本地读取缓存
responseStart HTTP 开始接收响应的时间(获取到第一个字节),包括从本地读取缓存
secureConnectionStart HTTPS 连接开始的时间,如果不是安全连接,则值为 0
unloadEventEnd 和 unloadEventStart 相对应,返回前一个网页 unload 事件绑定的回调函数执行完毕的时间戳
unloadEventStart 前一个网页(与当前页面同域)unload 的时间戳,如果无前一个网页 unload 或者前一个网页与当前页面不同域,则值为 0

Navigation Timing Level 2

Navigation Timings involved as per the W3C spec - level2.png

Level 2标准废弃了level 1的timing和navigation这两个接口,取而代之的是定义了 PerformanceNavigationTiming 对象window.performance.getEntriesByType("navigation")[0]

常用来计算的参数

image.png

TTFB 首字节时间

TTFB(Time To First Byte):从发送请求到数据返回第一个字节所消耗时间

const { responseStart, requestStart } = performance.timing
const TTFB = responseStart - requestStart

FP 首次绘制

FP(First Paint) :第一个像素绘制到页面上的时间

const paint = performance.getEntriesByType('paint')
const FP = paint[0].startTime

FCP 首次内容绘制

FCP (First Contentful Paint) 首次内容绘制 标记浏览器渲染来自 DOM 第一位内容的时间点,该内容可能是文本、图像、SVG 甚至 元素

const paint = performance.getEntriesByType('paint')
const FCP = paint[1].startTime

FMP 首次有效绘制

FMP(First Meaningful Paint) 首次有效绘制: 例如,在 YouTube 观看页面上,主视频就是主角元素.
图片可以没加载完成,但整体的骨架已经加载完成了。
1秒内完成FMP的概率超过80%,那就代表这个网站是一个性能较好的网站

let FMP = 0
const performanceObserverFMP = new PerformanceObserver((entryList, observer) => {
  const entries = entryList.getEntries()
  observer.disconnect()
  FMP = entries[0].startTime
})
// 需要在元素中添加 elementtiming="meaningful"
performanceObserverFMP.observe({ entryTypes: ['element'] })

TTI 可交互时间

TTI (Time to Interactive) 可交互时间: DOM树构建完毕,可以绑定事件的时间

const { domInteractive, fetchStart } = performance.timing
const TTI = domInteractive - fetchStart

LCP 最大内容渲染

let LCP = 0
const performanceObserverLCP = new PerformanceObserver((entryList, observer) => {
  const entries = entryList.getEntries()
  observer.disconnect()
  LCP = entries[entries.length - 1].startTime
})
performanceObserverLCP.observe({ entryTypes: ['largest-contentful-paint'] })

DCL

DCL (DomContentloaded): 当 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,无需等待样式表、图像和子框架的完成加载

const { domContentLoadedEventEnd, fetchStart } = performance.timing
const DCL = domContentLoadedEventEnd - fetchStart

L 全部加载完毕

L (on/Load), 当依赖的资源(图片、文件等), 全部加载完毕之后才会触发

const { domContentLoadedEventEnd, fetchStart } = performance.timing
const DCL = domContentLoadedEventEnd - fetchStart

FID 首次输入延迟

FID (First Input Delay) 首次输入延迟: 指标衡量的是从用户首次与您的网站进行交互(即当他们单击链接,点击按钮等)到浏览器实际能够访问之间的时间

let FID = 0
const performanceObserverFID = new PerformanceObserver((entryList, observer) => {
  const entries = entryList.getEntries()
  observer.disconnect()
  FID = entries[0].processingStart - entries[0].startTime
})
performanceObserverFID.observe({ type: ['first-input'], buffered: true })

浏览器发起一个HTTP 请求过程

请求时间含义.png
请求各阶段.png

Chrome限制每个域名最多执行6个TCP连接。如果您一次请求十二个资源,前6个将开始,后6个将排队。一旦其中一个请求完成,队列中的第一个请求项目将开始其请求过程。

  • Queuing (排队)排队时间
  • Stalled (停滞)发送请求之前等待的时间
  • DNS lookup (DNS查找),
  • initial connection (初始连接)
  • SSL handshake (SSL握手)
  • Request sent (请求发送)发出网络请求所花费的时间
  • Waiting (等待)(到开始下载第一个字节的时间(TTFB))等待初始响应所花费的时间
  • Content Download (内容下载)接收响应数据所花费的时间

TTFB就是等待第一个响应字节的时间,建议在200ms以下,以下情况可能会导致高TTFB(延迟):

  1. 客户端和服务器之间的网络条件差,
  2. 要么,服务器端程序响应很慢。

实验数据收集工具

image.png

Lihgthouse

chrome 浏览器,F12打开开发者工具,ctrl + shift + P 搜索Lighthouse可以调出此工具

lighthouse.png

参数含义

参数.png

参数指标.png

参考

首屏时间(FCP) VS 白屏时间(FP)
网站性能指标这么多,你到底选对了吗?
使用 RAIL 模型衡量性能
页面生命周期:DOMContentLoaded,load,beforeunload,unload
首屏时间与domContentLoaded触发时机的关系
Web 性能优化-首屏和白屏时间
控制台了解认知---network
初探performance-监控网页与程序性能
前端性能的几个基础指标
关于Web页面全链路性能优化指南
Navigation Timing
Using Navigation Timing APIs to understand your webpage
前端页面性能优化总结

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容