记录我在使用浏览器Performance API遇到的问题

China☆狼群 提交于 2020-01-07 05:40:25

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

本文中Performance API指的是Navigation Timing API。这并不是一篇Navigation Timing API的介绍文章,而是我在使用中遇到的问题。

我在开发中遇到Navigation Timing API中的connectStart等时间节点并不是标准时间戳,而是0或者一个很小的数值,导致指标数据计算出错,尤其是IOS设备。原因如下:

IOS设备通过浏览器的前进后退按钮进入的页面,Navigation Timing API数据中connectStart,responseEnd等数据可能为0或者是一个比较小的数值,并不是对应时间点的时间戳。究其原因,IOS设备通过缓存读取页面时,Navigation Timing的计算与安卓实现不一致。

如果你还想了解下Navigation Timing API,可以继续往下看

Navigation Timing API

Navigation Timing API中包含全部的页面加载中关键节点的时间,例如navigationStart,connectEnd,responseEnd等时间。 具体的相关API可以去MDN查看, 浏览器支持程度也非常不错,移动端IOS9及以上,Android4及以上都支持,桌面端IE9也都支持。

一些常规的性能数据计算方法

DNS时间 = domainLookupEnd - domainLookupStart TCP时间 = connectEnd - connectStart 后端时间 = responseEnd - connectEnd

白屏时间 = domInteractive - navigationStart 整屏时间 = loadEventEnd - navigationStart

解析dom树耗时 = domComplete - domInteractive request请求耗时 = responseEnd - responseStart

我们团队就是按照如上指标来做的各个时间的统计,做了各种测试,线下数据都没什么问题。上线了以后拿到的首批数据中,后端时间计算出来竟然有负值,尤其在IOS设备下,苦苦寻找原因,终于发现问题所在。

IOS设备通过浏览器的前进后退按钮进入的页面,Navigation Timing API数据中connectStart,responseEnd等数据可能为0或者是一个比较小的数值,并不是对应时间点的时间戳。

关于首屏时间的定义

根据Navigation Timing API的时间,是没有办法计算首屏时间的,首屏时间也并没有严格的定义,我们团队采用的首屏时间如下

首屏时间 = (dom解析完毕 && 所有首屏图片加载完毕 )- navigationStart

标准

<table> <thead><tr> <th>属性</th> <th>含义</th> </tr></thead> <tbody> <tr> <td>navigationStart</td> <td>准备加载新页面的起始时间</td> </tr> <tr> <td>redirectStart</td> <td>如果发生了HTTP重定向,并且从导航开始,中间的每次重定向,都和当前文档同域的话,就返回开始重定向的timing.fetchStart的值。其他情况,则返回0</td> </tr> <tr> <td>redirectEnd</td> <td>如果发生了HTTP重定向,并且从导航开始,中间的每次重定向,都和当前文档同域的话,就返回最后一次重定向,接收到最后一个字节数据后的那个时间.其他情况则返回0</td> </tr> <tr> <td>fetchStart</td> <td>如果一个新的资源获取被发起,则 fetchStart必须返回用户代理开始检查其相关缓存的那个时间,其他情况则返回开始获取该资源的时间</td> </tr> <tr> <td>domainLookupStart</td> <td>返回用户代理对当前文档所属域进行DNS查询开始的时间。如果此请求没有DNS查询过程,如长连接,资源cache,甚至是本地资源等。 那么就返回 fetchStart的值</td> </tr> <tr> <td>domainLookupEnd</td> <td>返回用户代理对结束对当前文档所属域进行DNS查询的时间。如果此请求没有DNS查询过程,如长连接,资源cache,甚至是本地资源等。那么就返回 fetchStart的值</td> </tr> <tr> <td>connectStart</td> <td>返回用户代理向服务器服务器请求文档,开始建立连接的那个时间,如果此连接是一个长连接,又或者直接从缓存中获取资源(即没有与服务器建立连接)。则返回domainLookupEnd的值</td> </tr> <tr> <td>(secureConnectionStart)</td> <td>可选特性。用户代理如果没有对应的东东,就要把这个设置为undefined。如果有这个东东,并且是HTTPS协议,那么就要返回开始SSL握手的那个时间。 如果不是HTTPS, 那么就返回0</td> </tr> <tr> <td>connectEnd</td> <td>返回用户代理向服务器服务器请求文档,建立连接成功后的那个时间,如果此连接是一个长连接,又或者直接从缓存中获取资源(即没有与服务器建立连接)。则返回domainLookupEnd的值</td> </tr> <tr> <td>requestStart</td> <td>返回从服务器、缓存、本地资源等,开始请求文档的时间</td> </tr> <tr> <td>responseStart</td> <td>返回用户代理从服务器、缓存、本地资源中,接收到第一个字节数据的时间</td> </tr> <tr> <td>responseEnd</td> <td>返回用户代理接收到最后一个字符的时间,和当前连接被关闭的时间中,更早的那个。同样,文档可能来自服务器、缓存、或本地资源</td> </tr> <tr> <td>domLoading</td> <td>返回用户代理把其文档的 "current document readiness" 设置为 "loading"的时候</td> </tr> <tr> <td>domInteractive</td> <td>返回用户代理把其文档的 "current document readiness" 设置为 "interactive"的时候.</td> </tr> <tr> <td>domContentLoadedEventStart</td> <td>返回文档发生 DOMContentLoaded事件的时间</td> </tr> <tr> <td>domContentLoadedEventEnd</td> <td>文档的DOMContentLoaded 事件的结束时间</td> </tr> <tr> <td>domComplete</td> <td>返回用户代理把其文档的 "current document readiness" 设置为 "complete"的时候</td> </tr> <tr> <td>loadEventStart</td> <td>文档触发load事件的时间。如果load事件没有触发,那么该接口就返回0</td> </tr> <tr> <td>loadEventEnd</td> <td>文档触发load事件结束后的时间。如果load事件没有触发,那么该接口就返回0</td> </tr> </tbody> </table>

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!