【Javascript高级】如何获取浏览器请求数据的整个过程花费的所有时间详细信息(性能分析量化)

浏览器请求数据的整个过程花费的所有时间都包括哪些部分?

我们可以在Chrome Network Timing中可以查看一个请求在各个阶段所花费的时间:

1、Queueing

请求文件顺序的的排序
什么东西?
浏览器有线程限制的,发请求也不能所有的请求同时发送,所以,队列喽。
从添加到待处理队列
到实际开始处理的时间间隔标示

2、Stalled

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

3、DNS Lookup

时间执行DNS查找。每个新域pagerequires DNS查找一个完整的往返。 DNS查询的时间,当本地DNS缓存没有的时候,这个时间可能是有一段长度的,但是比如你一旦在host中设置了DNS,或者第二次访问,由于浏览器的DNS缓存还在,这个时间就为0了。

4、Initial connection

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

5、Request sent

请求第一个字节发出前到最后一个字节发出后的时间,也就是上传时间

6、Waiting(TTFB)

请求发出后,到收到响应的第一个字节所花费的时间(Time To First Byte),发送请求完毕到接收请求开始的时间;这个时间段就代表服务器处理和返回数据网络延时时间了。服务器优化的目的就是要让这个时间段尽可能短。

7、Content Download

收到响应的第一个字节,到接受完最后一个字节的时间,就是下载时间

window.performance.timing中的相关属性语义?

各字段的含义如下:
s t a r t T i m e \color{red}{startTime} startTime:有些浏览器实现为navigationStart,代表浏览器开始unload前一个页面文档的开始时间节点。比如我们当前正在浏览baidu.com,在地址栏输入google.com并回车,浏览器的执行动作依次为:unload当前文档(即baidu.com)->请求下一文档(即google.com)。navigationStart的值便是触发unload当前文档的时间节点。
如果当前文档为空,则navigationStart的值等于fetchStart。
r e d i r e c t S t a r t 和 r e d i r e c t E n d \color{red}{redirectStart和redirectEnd} redirectStartredirectEnd:如果页面是由redirect而来,则redirectStart和redirectEnd分别代表redirect开始和结束的时间节点;
unloadEventStart和unloadEventEnd:如果前一个文档和请求的文档是同一个域的,则unloadEventStart和unloadEventEnd分别代表浏览器unload前一个文档的开始和结束时间节点。否则两者都等于0;
f e t c h S t a r t \color{red}{fetchStart} fetchStart是指在浏览器发起任何请求之前的时间值。在fetchStart和domainLookupStart之间,浏览器会检查当前文档的缓存;
domainLookupStart和domainLookupEnd分别代表DNS查询的开始和结束时间节点。如果浏览器没有进行DNS查询(比如使用了cache),则两者的值都等于fetchStart;
c o n n e c t S t a r t 和 c o n n e c t E n d \color{red}{connectStart和connectEnd} connectStartconnectEnd分别代表TCP建立连接和连接成功的时间节点。如果浏览器没有进行TCP连接(比如使用持久化连接webscoket),则两者都等于domainLookupEnd;
s e c u r e C o n n e c t i o n S t a r t \color{red}{secureConnectionStart} secureConnectionStart:可选。如果页面使用HTTPS,它的值是安全连接握手之前的时刻。如果该属性不可用,则返回undefined。如果该属性可用,但没有使用HTTPS,则返回0;
r e q u e s t S t a r t \color{red}{requestStart} requestStart代表浏览器发起请求的时间节点,请求的方式可以是请求服务器、缓存、本地资源等;
r e s p o n s e S t a r t 和 r e s p o n s e E n d \color{red}{responseStart和responseEnd} responseStartresponseEnd分别代表浏览器收到从服务器端(或缓存、本地资源)响应回的第一个字节和最后一个字节数据的时刻;
d o m L o a d i n g \color{red}{domLoading} domLoading代表浏览器开始解析html文档的时间节点。我们知道IE浏览器下的document有readyState属性,domLoading的值就等于readyState改变为loading的时间节点;
d o m I n t e r a c t i v e \color{red}{domInteractive} domInteractive代表浏览器解析html文档的状态为interactive时的时间节点。domInteractive并非DOMReady,它早于DOMReady触发,代表html文档解析完毕(即dom tree创建完成)但是内嵌资源(比如外链css、js等)还未加载的时间点;
d o m C o n t e n t L o a d e d E v e n t S t a r t \color{red}{domContentLoadedEventStart} domContentLoadedEventStart:代表DOMContentLoaded事件触发的时间节点:
页面文档完全加载并解析完毕之后,会触发DOMContentLoaded事件,HTML文档不会等待样式文件,图片文件,子框架页面的加载(load事件可以用来检测HTML页面是否完全加载完毕(fully-loaded))。
d o m C o n t e n t L o a d e d E v e n t E n d \color{red}{domContentLoadedEventEnd} domContentLoadedEventEnd:代表DOMContentLoaded事件完成的时间节点,此刻用户可以对页面进行操作,也就是jQuery中的domready时间;
d o m C o m p l e t e \color{red}{domComplete} domComplete:html文档完全解析完毕的时间节点;
l o a d E v e n t S t a r t 和 l o a d E v e n t E n d \color{red}{loadEventStart和loadEventEnd} loadEventStartloadEventEnd分别代表onload事件触发和结束的时间节点

我们主要关注的性能指标有哪些?如何计算这些性能指标?

可以使用Navigation.timing 统计到的时间数据来计算一些页面性能指标,比如DNS查询耗时、白屏时间、domready等等。如下:

console.log('首屏图片加载完成 : ',window.lastImgLoadTime - window.performance.timing.navigationStart); //在最后一张图出来的时候打时间点
console.log('HTML加载完成 : ',window.loadHtmlTime - window.performance.timing.navigationStart);//在HTML后打时间点
console.log('首屏接口完成加载完成 : ',Report.SPEED.MAINCGI - window.performance.timing.navigationStart);//在首屏的接口打时间点
console.log('接口完成加载完成 : ',Report.SPEED.LASTCGI - window.performance.timing.navigationStart);//在所有接口打时间点

// 总结
DNS查询耗时 = domainLookupEnd - domainLookupStart 
TCP链接耗时 = connectEnd - connectStart 
request请求耗时 = responseEnd - responseStart 
解析dom树耗时 = domComplete - domInteractive 
白屏时间 = domloadng - fetchStart 
domready时间 = domContentLoadedEventEnd - fetchStart 
onload时间 = loadEventEnd - fetchStart 

Resource timing API

Resource timing API是用来统计静态资源相关的时间信息,详细的内容请参考W3C Resource timing。这里我们只介绍performance.getEntries方法,它可以获取页面中每个静态资源的请求,如下:

// test
window.performance.getEntries();
// output
connectEnd: 3.8300000014714897
connectStart: 3.8300000014714897
decodedBodySize: 177922
domComplete: 3912.8400000045076
domContentLoadedEventEnd: 2657.119999988936
domContentLoadedEventStart: 2531.6449999809265
domInteractive: 2529.324999981327
domainLookupEnd: 3.8300000014714897
domainLookupStart: 3.8300000014714897
duration: 3954.6700000064448
encodedBodySize: 30276
entryType: "navigation"
fetchStart: 3.8300000014714897
initiatorType: "navigation"
loadEventEnd: 3954.6700000064448
loadEventStart: 3913.02999999607
name: "https://blog.csdn.net/m0_37981569/article/details/93415954"
nextHopProtocol: "h2"
redirectCount: 0
redirectEnd: 0
redirectStart: 0
requestStart: 26.824999978998676
responseEnd: 649.7999999846797
responseStart: 581.6599999961909
secureConnectionStart: 0
serverTiming: []
startTime: 0
transferSize: 30452
type: "navigate"
unloadEventEnd: 0
unloadEventStart: 0
workerStart: 0

可以看到performance.getEntries返回一个数组,数组的每个元素代表对应的静态资源的信息。

封装一个页面性能分析的工具类

// 计算加载时间
function getPerformanceTiming () { 
    var performance = window.performance;

    if (!performance) {
        // 当前浏览器不支持
        console.log('你的浏览器不支持 performance 接口');
        return;
    }

    var t = performance.timing;
    var times = {};

    //【重要】页面加载完成的时间
    //【原因】这几乎代表了用户等待页面可用的时间
    times.loadPage = t.loadEventEnd - t.navigationStart;

    //【重要】解析 DOM 树结构的时间
    //【原因】反省下你的 DOM 树嵌套是不是太多了!
    times.domReady = t.domComplete - t.responseEnd;

    //【重要】重定向的时间
    //【原因】拒绝重定向!比如,http://example.com/ 就不该写成 http://example.com
    times.redirect = t.redirectEnd - t.redirectStart;

    //【重要】DNS 查询时间
    //【原因】DNS 预加载做了么?页面内是不是使用了太多不同的域名导致域名查询的时间太长?
    // 可使用 HTML5 Prefetch 预查询 DNS ,见:[HTML5 prefetch](http://segmentfault.com/a/1190000000633364)           
    times.lookupDomain = t.domainLookupEnd - t.domainLookupStart;

    //【重要】读取页面第一个字节的时间
    //【原因】这可以理解为用户拿到你的资源占用的时间,加异地机房了么,加CDN 处理了么?加带宽了么?加 CPU 运算速度了么?
    // TTFB 即 Time To First Byte 的意思
    // 维基百科:https://en.wikipedia.org/wiki/Time_To_First_Byte
    times.ttfb = t.responseStart - t.navigationStart;

    //【重要】内容加载完成的时间
    //【原因】页面内容经过 gzip 压缩了么,静态资源 css/js 等压缩了么?
    times.request = t.responseEnd - t.requestStart;

    //【重要】执行 onload 回调函数的时间
    //【原因】是否太多不必要的操作都放到 onload 回调函数里执行了,考虑过延迟加载、按需加载的策略么?
    times.loadEvent = t.loadEventEnd - t.loadEventStart;

    // DNS 缓存时间
    times.appcache = t.domainLookupStart - t.fetchStart;

    // 卸载页面的时间
    times.unloadEvent = t.unloadEventEnd - t.unloadEventStart;

    // TCP 建立连接完成握手的时间
    times.connect = t.connectEnd - t.connectStart;

    return times;
    }

你可能感兴趣的:(JavaScript学习,JS基础,Javascript高级,javascript)