Web的性能一定程度上影响了用户留存率,Google DoubleClick 研究表明:如果一个移动端页面加载时长超过 3 秒,用户就会放弃而离开。BBC 发现网页加载时长每增加 1 秒,用户就会流失 10%。我们希望通过监控来知道 web 应用性能的现状和趋势,找到 web 应用的瓶颈,某次发布后的性能情况怎么样,是否发布后对性能有影响,感知到业务出错的概率,业务的稳定性怎么样等问题都需要解答。
本文主要介绍了监控哪些指标,并列举了行业内的主要工具。
1 浏览器Performance指标说明
1.1 浏览器打开网页的各个阶段
1.2 Navigation Timing API
W3C的浏览器performance属性指标说明,不同的浏览器的支持程度可能存在差异。(以下参数均为无符号类型的long long类型UNIX时间戳)
interface PerformanceTiming {
readonly attribute unsigned long long navigationStart;
readonly attribute unsigned long long unloadEventStart;
readonly attribute unsigned long long unloadEventEnd;
readonly attribute unsigned long long redirectStart;
readonly attribute unsigned long long redirectEnd;
readonly attribute unsigned long long fetchStart;
readonly attribute unsigned long long domainLookupStart;
readonly attribute unsigned long long domainLookupEnd;
readonly attribute unsigned long long connectStart;
readonly attribute unsigned long long connectEnd;
readonly attribute unsigned long long secureConnectionStart;
readonly attribute unsigned long long requestStart;
readonly attribute unsigned long long responseStart;
readonly attribute unsigned long long responseEnd;
readonly attribute unsigned long long domLoading;
readonly attribute unsigned long long domInteractive;
readonly attribute unsigned long long domContentLoadedEventStart;
readonly attribute unsigned long long domContentLoadedEventEnd;
readonly attribute unsigned long long domComplete;
readonly attribute unsigned long long loadEventStart;
readonly attribute unsigned long long loadEventEnd;
};
- navigationStart
表征了从同一个浏览器上下文的上一个文档卸载(unload)结束时的时间戳。如果没有上一个文档,这个值会和fetchStart相同。 - unloadEventStart
表征了unload事件抛出时的时间戳。如果没有上一个文档,或者上一个文档需要重定向,或者重定向中的一个不同源,这个值会返回0。 - unloadEventEnd
表征了unload事件处理完成时的时间戳。如果没有上一个文档,或者上一个文档需要重定向,或者重定向中的一个不同源,这个值会返回0。 - redirectStart
表征了第一个HTTP重定向开始时的时间戳。如果没有重定向,或者重定向中的一个不同源,这个值会返回0。 - redirectEnd
表征了最后一个HTTP重定向完成时(也就是说是HTTP响应的最后一个比特直接被收到的时间)的时间戳。如果没有重定向,或者重定向中的一个不同源,这个值会返回0。 - fetchStart
表征了浏览器准备好使用HTTP请求来获取(fetch)文档的时间戳。这个时间点会在检查任何应用缓存之前。 - domainLookupStart
表征了域名查询开始的时间戳。如果使用了持续连接(persistent connection),或者这个信息存储到了缓存或者本地资源上,这个值将和fetchStart一致。 - domainLookupEnd
表征了域名查询结束的时间戳。如果使用了持续连接(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 (en-US) 被触发时的时间戳。 - loadEventStart
返回该文档下,load事件被发送时的时间戳。如果这个事件还未被发送,它的值将会是0。 - loadEventEnd
返回当load事件结束,即加载事件完成时的时间戳。如果这个事件还未被发送,或者尚未完成,它的值将会是0。
1.3 Navigation Timing API兼容性
目前Navigation Timing已经普及,绝大部分主流浏览器都已经支持,因此前端性能在各个浏览器上将得到很好的测量。
1.4 网页性能数据计算方法
1.4.1 页面加载完成的时间
这几乎代表了用户等待页面可用的时间
loadPage = loadEventEnd - navigationStart;
1.4.2 DOM 树结构解析时间
DOM 树嵌套层数多的话,会导致该时间大大延长。
domReady = domComplete - responseEnd;
1.4.3 重定向的时间
比如,http://example.com/写成http://example.com就会导致一次重定向。
redirect = redirectEnd - redirectStart;
1.4.4 DNS 查询时间
建议做DNS 预加载,页面内是不是使用了太多不同的域名导致域名查询的时间太长。
可使用HTML5 Prefetch预查询DNS,见:HTML5 prefetch
lookupDomain = domainLookupEnd - domainLookupStart;
1.4.5 读取页面第一个字节的时间(白屏时间)
这可以理解为用户拿到资源占用的时间,通过异地机房了么、CDN 处理、加带宽、提高CPU运算速度的方式缩短该时间。
ttfb = responseStart - navigationStart;
1.4.6 内容加载完成的时间
页面内容经过gzip压缩、静态资源css/js等压缩。
request = responseEnd - requestStart;
1.4.7 Onload回调函数的时间
太多不必要的操作都放到 onload 回调函数里执行了会导致该时间加长,可以考虑延迟加载、按需加载的策略。
loadEvent = loadEventEnd - loadEventStart;
1.4.8 DNS 缓存时间
appcache = domainLookupStart - fetchStart;
1.4.9 卸载页面时间
unloadEvent = unloadEventEnd - unloadEventStart;
1.4.10 TCP 建立连接完成握手的时间
connect = connectEnd - connectStart;
2 现有涉及前端性能的工具和服务
2.1 前端性能监测工具和服务
以下为作者调研到的39款现有的涉及到前端性能监控的工具或者服务,以名称、官网、开源情况几个方面进行了列举。(如有未收录的新工具欢迎联系我更新)
作者将后期将专门写文章介绍各个工具的特性。
3 参考资料
[1] Navigation Timing
[2] Navigation Timing Level 2
[3] PerformanceTiming
[4] Navigation Timing API
[5] 监控网页与程序性能