Resource Timing API提供了让用户查看一个资源从输入url到下载下来经历的各个过程所消耗的时间,借此可以来衡量网站的性能。我们可以通过Resource Timing Api监控哪个阶段消耗时间比较长,然后针对该阶段进行优化。了解网络下载资源的阶段至关重要。这是修复加载问题的基础。

一、浏览器DevTools

Queueing队列
排队的时间花费。可能由于该请求被渲染引擎认为是优先级比较低的资源(图片)、服务器不可用、超过浏览器并发请求的最大连接数(Chrome的最大并发连接数是6)。

Stalled / Blocking停止/阻塞
是浏览器得到要发出这个请求的指令,到请求可以发出的等待时间,一般是代理协商、以及等待可复用的TCP连接释放的时间,不包括DNS查询、建立TCP连接等时间等。

Proxy negotiation代理协商
与代理服务器连接的时间花费(如有)。
主要是浏览器通过代理服务器去服务目标服务,如本地代理Fiddler,一般无法优化。

DNS LookupDNS查找
执行DNS查找的时间,每个新域pagerequires DNS查找一个完整的往返。 DNS查询的时间,当本地DNS缓存没有的时候,这个时间可能是有一段长度的。

Initial connection / Connecting初始连接/连接
建立TCP连接的时间,就相当于客户端从发请求开始到TCP握手结束这一段,包括DNS查询+Proxy时间+TCP握手时间。

SSL安全套接层
(Secure Sockets Layer 安全套接层)及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS与SSL在传输层对网络连接进行加密。

Request sent / Sending请求已发送/正在发送
请求第一个字节发出前到最后一个字节发出后的时间(上传时间)。

Waiting(TTFB)等待响应
请求发出后,到收到响应的第一个字节所花费的时间(Time To First Byte)。
通常是耗费时间最长的,通常受到线路、服务器距离等因素的影响。它包含了TCP连接时间,发送HTTP请求时间和获得响应消息第一个字节的时间。

Content Download / Downloading内容下载/下载
收到响应的第一个字节,到接受完最后一个字节的时间(下载时间)。
浏览器开始收到服务器响应数据的时间=后台处理时间+重定向时间,是反映服务端响应速度的重要指标。


二、Resource Timing Api

所有网络请求都被视为资源。当它们通过网络检索时,分为不同的生命周期。Network(网络)面板使用的Resource Timing API和提供给开发者的API是一样的。

注意: 当使用跨源资源的Resource Timing API时, 请确保所有资源都有CORS头信息。Resource Timing API提供了关于每个单独资源接收时间的详细信息。

请求生命周期的主要阶段是:

Redirect
立即开始startTime。
如果发生重定向, redirectStart也会开始计时。
如果重定向发生在此阶段结束时,那么redirectEnd将被采用。

App Cache
如果浏览器有缓存,将采用fetchStart时间。

DNS
domainLookupStart 记录DNS请求开始的时间。
domainLookupEnd 记录DNS请求结束的时间。

TCP
connectStart 记录开始连接到服务器的时间。
如果用了TLS或SSL,secureConnectionStart记录开始连接时间。
connectEnd 记录连接完毕时间。

Request
requestStart记录请求发送到服务器的时间。

Response
responseStart记录最开始的响应时间。
responseEnd记录响应结束时间。

通过window.performance.getEntriesByType(‘resource’)获取所有的PerformanceResourceTiming:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if('performance' in window) {
// 获取的是所有的PerformanceResourceTiming
var resources = window.performance.getEntriesByType('resource')
// 遍历各个资源加载的时间
resources.map((resource) => {
// 这里以图片为例,判断图片加载的时间
if(resource.initiatorType === 'img') {
// duration取的是整个过程中经历的时间,即startTime到responseEnd直接的时间,
// 即等于resource.responseEnd - resource.startTime
if(resource.duration > 5000) {
// 图片加载超过了5秒了,上报服务器,提示图片加载过长
reportToServer()
}
}
})
}

注意,上面的代码需要在onload事件上面执行(onload会在图片加载完毕以后调用)。

PerformanceResourceTimeing包含以下的属性:

initiatorType:资源的类型,有img、script、link

下面的属性是以毫秒为单位,对应上图

  • redirectStart

  • redirectEnd

  • fetchStart

  • domainLookupStart

  • domainLookupEnd

  • connectStart

  • connectEnd

  • secureConnectionStart

  • requestStart

  • responseStart

  • responseEnd

所以我们得出这样的一个计算:
查看DNS查询时间: domainLookupEnd - domainLookupStart
查看TCP三次握手时间: connectEnd - connectStart
request请求时间: responseEnd - responseStart
整个过程时间: responseEnd - startTime 或者 duration


参考文章: