performance.timing

window.performance.timing 是W3C规范提供的接口,可以通过它获取到用户访问一个页面的每个阶段的精确时间(timestamp), 从而对性能进行分析

timer_inner

timing 含义
navigationStart 同一个浏览器上一个文档卸载(unload)结束时的时间戳。如果没有上一个文档,这个值会和 fetchStart 相同
redirectStart 第一个HTTP重定向开始时的时间戳。如果没有重定向,或者上次重定向不是同源的,这个值会返回0
unloadEventStart 上一个文档 unload 事件抛出时的时间戳。如果没有上一个网页,或者之前的网页跳转不是属于同一个域内,则返回值为0
unloadEventEnd 上一个网页 unload 事件结束时的时间戳。如果没有前一个网页,或者之前的网页跳转不是属于同一个域内,则返回值为0
redirectEnd 最后一个HTTP重定向完成时的时间戳。如果没有重定向,或者上次重定向不是同源的,这个值会返回0
fetchStart 浏览器准备好使用HTTP请求来获取(fetch)文档的时间戳。这个时间点会在检查任何应用缓存之前
domainLookupStart DNS 域名查询开始的时间戳。如果使用持久连接(persistent connection),或者这个信息存储到了缓存或者本地资源上,这个值将和 fetchStart 一致
domainLookupEnd DNS 域名查询完成的时间戳。如果使用持久连接(persistent connection),或者这个信息存储到了缓存或者本地资源上,这个值将和 fetchStart 一致
connectStart HTTP请求开始向服务器发送时的时间戳。如果使用持久连接(persistent connection),则返回值等同于 fetchStart 属性的值
connectEnd 浏览器与服务器之间的连接建立时的时间戳。如果建立的是持久连接,则返回值等同于 fetchStart 属性的值
secureConnectionStart 浏览器与服务器开始安全链接的握手时的时间戳。如果当前网页不要求安全连接,则返回0
requestStart 浏览器向服务器发出HTTP请求时(或开始读取本地缓存时)的时间戳
responseStart 浏览器从服务器收到(或从本地缓存读取)第一个字节时的时间戳。如果传输层在开始请求之后失败并且连接被重开,该属性将会被设置成新的请求相对应的发起时间
responseEnd 浏览器从服务器收到(或从本地缓存读取,或从本地资源读取)最后一个字节时(如果在此之前HTTP连接已经关闭,则返回关闭时)的时间戳
domLoading 当前网页DOM结构开始解析时(即Document.readyState属性变为 ‘loading’ 、相应的 readystatechange 事件触发时)的时间戳
domInteractive 当前网页DOM结构结束解析、开始加载内嵌资源时(即Document.readyState属性变为 ‘interactive’ 、相应的readystatechange 事件触发时)的时间戳
domContentLoadedEventStart 当解析器发送 DOMContentLoaded 事件,即所有需要被执行的脚本已经被解析时的时间戳
domContentLoadedEventEnd 当所有需要立即执行的脚本已经被执行(不论执行顺序)时的时间戳
domComplete 当前文档解析完成,即 Document.readyState 变为 ‘complete’且相对应的 readystatechange 被触发时的时间戳
loadEventStart 该文档下,load 事件被发送时的时间戳。如果这个事件还未被发送,它的值将会是0
loadEventEnd 当 load 事件结束,即加载事件完成时的时间戳。如果这个事件还未被发送,或者尚未完成,它的值将会是0

性能指标

DNS解析耗时: domainLookupEnd - domainLookupStart
TCP连接耗时: connectEnd - connectStart
SSL安全连接耗时: connectEnd - secureConnectionStart
网络请求耗时(TTFB): responseStart - requestStart
数据传输耗时: responseEnd - responseStart
DOM解析耗时: domInteractive - responseEnd
资源加载耗时: loadEventStart - domContentLoadedEventEnd
首包时间: responseStart - domainLookupStart
首次渲染时间 / 白屏时间: responseEnd - fetchStart
首次可交互时间: domInteractive - fetchStart
DOM Ready时间: domContentLoadEventEnd - fetchStart
页面完全加载时间: loadEventStart - fetchStart

性能统计

利用 performance.timing 可以获取到每个阶段的耗时数据,但是不同的人在不同的环境、不同的时间访问同一页面时,统计到的时间是不同的,单次的数据并不能反映页面全局的表现,要想知道该页面的整体性能,需要对统计到的所有数据做一个处理,使得我们对页面的每次变更有一个直观的认识,为用户页面性能调优提供依据。

  1. 平均值统计法

收集到一段时间区间中所有用户访问应用的性能数据,将这些数据做均值处理,最终给到这个时间区间的平均耗时数据。
这种统计方法简单粗暴,其中长尾数据(可能占比较少但性能十分差的数据)很大程度上会影响均值的大小,导致给出的均值无法很好的表现性能情况;同时性能数据分布情况不清楚,无法制定优化方案。

  1. 百分位数统计法

将数据从小到大排列,处于第n%个数据称为n分位数, 表示n%的性能数据均小于等于该值,那剩下的(1-n%)的数据均大于该值。
线上通常 n 取 80 或者 90,代表了 80%/90% (大部分)的用户的性能数据好于我们的基准值的一个情况。与平均值统计方法不同,百分位数统计法会给到几个主要的百分位数的性能数据值,但对于整体的样本情况没有直观的认识。

  1. 样本分布统计法

将性能样本数据进行分桶统计,为了防止桶的个数太多,并且不给实时统计带来很大压力,可以使用不均匀的桶进行统计。对于性能数据,大家会非常关注10s内的样本分布情况,对于10s之后的数据桶可以粗放设置。
通过样本分布统计法,可以给用户提供非常直观的样本性能分布情况。通过分布直方图可以很直观的知道页面在指定时间区间内的样本占比。

performance.mark & performance.measure

  • mark() 方法在浏览器的性能入口缓冲区(performance entry buffer)中使用给定名称添加一个时间戳
  • clearMarks() 这个方法可以从浏览器的性能入口缓冲区 (performance entry buffer) 中移除声明的标记。如果调用这个方法时没有传递参数, 则所有带有 entry type 这类标记的 performance entries 将从 performance entry 缓存区中被移除
  • measure() 方法在浏览器性能入口缓冲区中创建了一个已命名的时间戳来记录两个特殊标志位(通常称为开始标志和结束标志)。 被命名的时间戳称为测量(measure)
  • clearMeasures() 方法可以从浏览器的性能入口缓冲区中移除声明的measure。如果这个方法被调用时没有传入参数,则所有 entry type 标记值为 measure 的性能实体将被从性能入口缓冲区中移除
  • getEntries() 对于给定的 filter ,此方法返回 PerformanceEntry 对象数组

可以结合 mark & measure 方法获取程序运行过程中的差值,进而进行性能监控与分析。

废弃的属性

performance.timing 属性在 Navigation Timing Level 2 specification 中已经被废弃,推荐使用 PerformanceNavigationTiming 来获取浏览器相关的时间节点