利用Resource Timing监控资源加载速度

栏目: CSS · 发布时间: 5年前

内容简介:浏览器从请求资源到资源下载下来,会经过多个阶段,一个请求生命周期的主要阶段包括:我们可以借助chrome的devtools查看,在network选项卡下,点击某个请求,选中Timing就可以看到devtools给我们提供的关于timing resource各个阶段的详细时间了。Queueing: 请求被阻塞,放入等待队列中等待。

浏览器从请求资源到资源下载下来,会经过多个阶段,一个请求生命周期的主要阶段包括:

  1. 重定向;如果服务器返回302的状态时,则会发生重定向,页面会重定向到302响应的location属性指定的地址去(response的Location属性指定,例如jd.com会被跳转到http://www.jd.com)。
  2. 读取浏览器缓存;如果资源的缓存时间还未过期(服务器设置的expires和cache-control还未过期),则会直接从浏览器缓存中读取。后续的dns查询、tcp握手、请求的发送都不会进行了。
  3. DNS解析;发送http请求需要通过建立TCP连接,建立TCP连接需要直到目标机器(服务器)的ip地址,所以需要进行dns的解析出ip,然后通过socket建立tcp连接。
  4. TCP握手;http建立在TCP上,需要先完成TCP三次握手,通过第2步的ip和已知的端口号,浏览器开启一个进程建立TCP连接。在此过程中,如果使用https,则会在TCP连接的时候进行SSL握手,建立SSL连接。
  5. 请求request;浏览器根据url,组装http请求,并发送。
  6. 接收response;服务器返回http响应的时候,浏览器接收到http response,然后就下载资源了。
利用Resource Timing监控资源加载速度
图1

查看各个阶段资源加载时间

devtools

我们可以借助chrome的devtools查看,在network选项卡下,点击某个请求,选中Timing就可以看到devtools给我们提供的关于timing resource各个阶段的详细时间了。

利用Resource Timing监控资源加载速度
图2

Queueing: 请求被阻塞,放入等待队列中等待。

一般以下几个原因会被阻塞:

1、如果这个资源加载优先级比较低,比如图片(html/css/js的优先级比图片高),那么图片请求就会被渲染引擎阻塞,等待优先级高的资源加载完成才从队列中取出,等待发送。

2、我们知道浏览器对同一域名下对TCP连接的并发数有限制(防止资源被消耗殆尽),chrome这边是6,那么如果同一域名下请求多于6的话,后面的请求就会被阻塞。

3、等待释放TCP连接

Stalled: 等待发送所用的时间,原因同上。

DNS Lookup:DNS查询时间

Initail connection:建立TCP连接所用的时间

SSL:建立SSL连接所用的时间

Request sent:发出请求的时间,通常不到一毫秒

TTFB:第一字节时间,即请求发出到接受到服务器第一个字节的时间,如果这个时间太长,一般有两个原因:

1、网络太差

2、服务器响应太慢

一般建议不要这个阶段的时间不要超过200毫秒。

Content Download:资源下载时间,如果被阻塞,则这个时间会很长,或者资源过大也会导致下载时间过长。例如js执行时间过长,那么图片加载下来的时间就会被拉到很长。

Resource Timing Api

现代浏览器提供了Api让用户可以查看图1各个阶段所消耗的时间,以便用户用Api获取资源加载过程中的具体情况,排查耗时的阶段,然后进行对应的优化。

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

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

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

PerformanceResourceTimeing包含以下的属性:

  • [x] initiatorType:资源的类型,有img、script、link

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

  • [x] redirectStart
  • [x] redirectEnd
  • [x] fetchStart
  • [x] domainLookupStart
  • [x] domainLookupEnd
  • [x] connectStart
  • [x] connectEnd
  • [x] secureConnectionStart
  • [x] requestStart
  • [x] responseStart
  • [x] responseEnd

所以我们得出这样的一个计算:

查看DNS查询时间: domainLookupEnd - domainLookupStart

查看TCP三次握手时间: connectEnd - connectStart

request请求时间: responseEnd - responseStart

整个过程时间: responseEnd - startTime 或者 duration

资源加载

浏览器渲染过程(关键渲染路径)

1、根据HTML构建DOM树

2、根据css构建CSSOM规则树

3、根据DOM树和CSSOM树渲染合并渲染树

4、根据渲染树计算元素的位置和大小

5、将元素显示在屏幕上

在此过程中,解析到script会阻塞dom的解析和渲染(但其他资源的下载还是并行下载的)。执行完js后又会重新构建DOM树和CSSOM树,再构建渲染树,如此反复。

利用Resource Timing监控资源加载速度

css加载

css被视为阻塞渲染的资源,不会阻塞dom的解析,但会阻塞dom的渲染。浏览器为了避免dom渲染完后,css样加载完再去渲染一次,就会阻塞dom的渲染。不然会有两次渲染,从性能上和用户体验上都不好。

如果把加载css放在body后,浏览器为了防止上面的状况的发生,会等待css加载完才去渲染dom,这样就会白屏了,所以建议css放在head里去加载。

所以,css放在head加载是一个很好的优化。

js加载

js即会阻塞dom的解析,也会阻塞dom的渲染。js是单线程的,在执行js的时候,浏览器会将控制权交给js,dom解析和渲染都会阻塞。

如果把js加载放在头部,那么dom的解析和渲染就停止了,这样会导致两个问题:

1、一方面,如果这时候js要获取dom或者操作dom都会报错。

2、另一方面,用户等待页面展示出来的时间也会加长,所以建议js加载放在底部。

备注:如果都放在head中,css在前,js在后,则浏览器为了让js获取到的样式是准确的,则会在css加载完前阻塞js的执行。如果把js写在前,css在后,浏览器会预加载css,这样的效果会比css在前阻塞后面的js执行好。

我们可以将script的加载设为异步加载,即defer/async,这样它就不会阻塞dom的解析和渲染。

结合以上,我们建议把css的引入放在head,把js的引入放在body之后,如果js可以异步加载,我们可以使用异步加载的方式。多说一句,现代浏览器有freload和frefetch的预加载,也可以提高页面加载速度,有兴趣的可以去查阅下资料。


以上所述就是小编给大家介绍的《利用Resource Timing监控资源加载速度》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C程序设计的抽象思维

C程序设计的抽象思维

Eric S.Roberts / 闪四清 / 机械工业出版社 / 2012-5 / 99.00元

Eric S. Roberts所著的《C程序设计的抽象思维》是一本关于C语言的经典图书。本书共计17章,分为4部分,第一部分概述计算机导论课程中涉及的基本编程概念;第二部分讨论递归算法,其中结合大量示例,有助于读者轻松理解和掌握晦涩的概念;第三部分不仅介绍了用非递归算法实现的抽象数据类型,还提供了一些工具,有助于读者理解数据抽象的概念;第四部分重点介绍采用递归算法实现的抽象数据类型。本书重点突出,......一起来看看 《C程序设计的抽象思维》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具