ronghaoZHI/ronghaoZHI.github.io

页面加载过程耗时分析

Opened this issue · 0 comments

页面加载时间

浏览器都是有开发者调试模式的,以chrome为例,打开页面后,按ctrl+shift+i,或者点击右键菜单里的检查,就进入了开发者模式,开发者模式里面有很多功能,跟页面加载时间相关的就是network标签。如下图所示:
image
在最下面的数据反应了该页面的整体加载情况。比如总共有111个请求,5.8M的数据,以及三个时间点,finish、DOMContentLoaded 和 load。
finish:页面最后一个请求截止的时间,如果页面加载完后,触发了ajax请求,那么该时间会变更。
DOMContentLoaded:dom内容加载并解析完成的时间
load:页面所有的资源(图片,音频,视频等)加载完成的时间

那什么是dom内容加载完毕呢?我们从打开一个网页说起。当输入一个URL,页面的展示首先是空白的,然后过一会,页面会展示出内容,但是页面的有些资源比如说图片资源还无法看到,此时页面是可以正常的交互,过一段时间后,图片才完成显示在页面。从页面空白到展示出页面内容,会触发DOMContentLoaded事件。而这段时间就是HTML文档被加载和解析完成。

在这里我们可以明确DOMContentLoaded所计算的时间,当文档中没有脚本时,浏览器解析完文档便能触发 DOMContentLoaded 事件;如果文档中包含脚本,则脚本会阻塞文档的解析,而脚本需要等位于脚本前面的css加载完才能执行。在任何情况下,DOMContentLoaded 的触发不需要等待图片等其他资源加载完成。

接下来,我们来说说load,页面上所有的资源(图片,音频,视频等)被加载以后才会触发load事件,简单来说,页面的 load事件会在 DOMContentLoaded 被触发之后才触发。

通俗来讲就是 DOMContentLoaded 是页面白屏的时间,load是通常所说的页面加载完成,浏览器不再转菊花的时间。


影响页面加载的因素

- js性能太差,阻塞页面

浏览器解析过程中,遇到<script>标签的时候,便会停止解析过程,转而去处理脚本,如果脚本是内联的,浏览器会先去执行这段内联的脚本,如果是外链的,那么先会去加载脚本,然后执行。在处理完脚本之后,浏览器便继续解析HTML文档。

- 某个请求慢阻塞页面的加载

一般遇到页面卡顿,我们首先都是会想到去network里面去查看,可以一眼便能看出页面具体的加载时间,以及每一个请求的详细耗时。


同域名下的请求数过多导致Queueing

- 单个请求的各个时间段的含义

image
Queueing 请求排队的时间。关于这个,需要知道一个背景,就是浏览器与同一个域名建立的TCP连接数是有限制的,chrome设置的6个,如果说同一时间,发起的同一域名的请求超过了6个,这时候就需要排队了,也就是这个Queueing时间

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

优化措施:
1、将资源合理分布到多台主机上,可以提高并发数,但是增加并行下载数量也会增大开销,这取决于带宽和CPU速度,过多的并行下载会降低性能;
2、脚本置于页面底部;

DNS Lookup DNS查询的时间,页面内任何新的域名都需要走一遍 完整的DNS查询过程,已经查询过的则走缓存

优化措施:
1、利用DNS缓存(设置TTL时间);
2、利用Connection:keep-alive特性建立持久连接,可以在当前连接上进行多个请求,无需再进行域名解析;

Initial Connection / Connecting 建立TCP连接的时间,包括TCP的三次握手和SSL的认证

SSL 完成ssl认证的时间

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

优化措施:
1、减少HTTP请求,可以使用CSS Sprites、内联图片、合并脚本和样式表等;
2、对不常变化的组件添加长久的Expires头(相当于设置久远的过期时间),在后续的页面浏览中可以避免不必要的HTTP请求;

Waiting 请求发出后,到收到响应的第一个字节所花费的时间(Time To First Byte)

优化措施:
1、使用CDN,将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求,提高响应速度;

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

优化措施:
1、通过条件Get请求,对比If-Modified-Since和Last-Modified时间,确定是否使用缓存中的组件,服务器会返回“304 Not Modified”状态码,减小响应的大小;
2、移除重复脚本,精简和压缩代码,如借助自动化构建工具gulp webpack等;
3、压缩响应内容,服务器端启用gzip压缩,可以减少下载时间;