一般情况下,如果网页加载时间超过 5s,用户就会感觉页面比较卡,用户体验相当差,用户可能会直接走人,所以加载的时间对于一个网站来说还是相当重要的。那做项目的时候怎样分析页面的加载速度慢呢?
首先我们要知道影响页面加载的因素
- JS 性能太差,阻塞页面
浏览器解析过程中,遇到 <script> 标签的时候,便会停止解析过程,转而去处理脚本,如果脚本是内联的,浏览器会先去执行这段内联的脚本,如果是外链的,那么先会去加载脚本,然后执行。在处理完脚本之后,浏览器便继续解析 HTML 文档。
遇到 JS 阻塞的情况,就需要具体去看代码的具体逻辑。
- 某个请求慢阻塞页面的加载
一般遇到页面卡顿,首先去 Network 里面去查看每个页面所有请求的状态及具体的加载时间,以及每一个请求的详细耗时。如果状态有非 200,如 pending,则去检查对应的请求。
- 同域名下的请求数过多导致 Queueing
就是浏览器与同一个域名建立的 TCP 连接数是有限制的,比方 chrome 设置的是 6 个,如果说同一时间,发起的同一域名的请求超过了 6 个,这时候就需要排队了,也就是这个 Queueing 时间。
HTML 页面是如何完成
当我们在浏览器输入 url 按下 Enter 后,浏览器拿到你输入的 url,解析出域名【domain.com】得到域名之后进行 DNS 查询(TCP/IP 协议中连接是需要知道 IP 地址),解析得到域名 IP,然后与服务器建立连接,再与该 IP 地址来三次经典的握手建立 TCP 连接,如果协议头是 http 则与目标 IP 的 80 端口通信,如果是 https 则是 443 端口,建立好 TCP 连接后,就可以发送 http 请求了,浏览器发起请求,服务器响应并返回内容,最终就是我们所看到的页面内容。
查看页面加载时间
以 chrome 为例,打开页面后,按 F12 或者点击右键菜单里的检查,就进入了开发者模式,开发者模式里面有很多功能,跟页面加载时间相关的就是 Network 标签。如下图所示:
依次是 17 个请求;622K 数据;页面最后一个请求截止用时 1.7s;DOM 内容加载并解析完成用时 1.48;页面所有的资源(图片,音频,视频等)加载完成用时 1.58s
Finish:页面最后一个请求截止的时间,如果页面加载完后,触发了 ajax 请求,那么该时间会加长。
DOMContentLoaded:DOM 内容加载并解析完成的时间。(通俗来讲就是是页面白屏的时间)
load:页面所有的资源(图片,音频,视频等)加载完成的时间。(页面加载完成,浏览器不再转圈的时间,页面上所有的资源(图片,音频,视频等)被加载以后才会触发 load 事件,简单来说,页面的 load 事件会在 DOMContentLoaded 被触发之后才触发。)
一般情况下 html 页面在解析渲染的过程中,会有大量的请求,比如外链的 css、js、图片等等,这些资源都需要浏览器去重新发起 http 请求。这些请求其实都是类似的一个过程。
首先我们打开 F12 开发都工具的 Network 标签,看看单个请求的各个时间段(不同的时段分别有不同的颜色区分),将鼠标悬停在 waterfall 字段就可以看到这个请求具体的耗时,如下图所示:
各个时间段的含义
Queueing
请求排队的时间。就是浏览器与同一个域名建立的 TCP 连接数是有限制的,比方 chrome 设置的 6 个,如果说同一时间,发起的同一域名的请求超过了 6 个,这时候就需要排队了,也就是这个 Queueing 时间。Stalled
就是浏览器得到要发出请求的指令到请求可以发出的等待时间,一般是代理协商、以及等待可复用的 TCP 连接释放的时间,不包括 DNS 查询、建立 TCP 连接等时间等。Stalled/Blocking
请求能够被发出去前的等等时间。包含了用于处理代理的时间。另外,如果有已经建立好的连接,那么这个时间还包括等待已建立连接被复用的时间,这个遵循浏览器对同一源最大 TCP 连接的规则。Proxy Negotiation
处理代理的时间。DNS Lookup
DNS 查询的时间,页面内任何新的域名都需要走一遍 完整的 DNS 查询过程,已经查询过的则走缓存。Initial Connection / Connecting
建立 TCP 连接的时间,包括 TCP 的三次握手和 SSL 的认证。SSL
完成 ssl 认证的时间Request sent/sending
请求第一个字节发出前到最后一个字节发出后的时间,也就是上传时间。Waiting
请求发出后,到收到响应的第一个字节所花费的时间。Content Download
收到响应的第一个字节,到接受完最后一个字节的时间,就是下载时间。
深入分析页面的性能
粗略扫一眼请求的时间,都是清一色几十毫秒。这时候我们可以在 Network 里瀑布般的 Timeline 里很直观的看出来请求的耗时情况。
在 timeline 里,每一条线代表一个 TCP 的连接,每一种颜色代表请求一个时间段,每条线的颜色一直循环变化,从灰色到深绿最后蓝色,然后又变灰色,说明浏览器建立的 TCP 连接一直在循环复用,这样就省去了三次握手的时间。
有一条蓝色竖线和红色竖线,蓝色竖线表示触发 DomContentLoad 事件触发时间,红色表示 Load 事件触发,如下图:
开发者工具的 Performance