You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
17 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 31 | 工欲善其事必先利其器:前端性能测试工具原理与行业常用工具简介
你好,我是茹炳晟。今天我和你分享的主题是:工欲善其事必先利其器之前端性能测试工具原理与行业常用工具简介”。
不同于后端性能测试知识的琐碎、独立今天我将从问答形式回到正常的分享思路上为你介绍前端性能测试工具为。我会以一个具体网站为例和你分析WebPagetest的用法以及前端性能相关的主要概念与指标。
## WebPagetest功能简介
WebPagetest是前端性能测试的利器
* 可以为我们提供全方位的量化指标,包括页面的加载时间、首字节时间、渲染开始时间、最早页面可交互时间、页面中各种资源的字节数、后端请求数量等一系列数据;
* 还可以自动给出被测页面性能优化水平的评价指标,告诉我们哪些部分的性能已经做过优化处理了,哪些部分还需要改进;
* 同时还能提供Filmstrip视图、Waterfall视图、Connection视图、Request详情视图和页面加载视频慢动作。
可以说WebPagetest为我们提供了前端页面性能测试所需要的一切而且还是免费的。接下来我们就通过测试一个具体的网站实践一下它的强大功能以及具体使用方法吧。
## 使用WebPagetest测试某网站的首页
那么,接下来我就以某网站首页的前端性能测试和评估为例,和你一起看看如何使用这个强大的前端性能工具。
**首先访问WebPagetest的主页“[http://www.webpagetest.org/”](http://www.webpagetest.org/%E2%80%9D) ,也就是工具的使用界面。**
1. 将被测页面的地址填写到被测Website URL栏中
2. 选择测试发起的地域Test Location以及你希望使用的浏览器这里我选择了美国旧金山、Chrome浏览器。
WebPagetest在全球各大洲的很多国家和地区都有自己的测试代理机这些测试代理机可能是虚拟机也可能是真机还有很多是建立在Amazon EC2上的云端机器。另外WebPagetest除了支持各种浏览器以外还支持主流的Android设备和Apple设备。
**然后,选择需要模拟的网络情况**。这里我选择了有线网络Cable当然你也可以根据你的测试要求选择各种3G或者4G移动网络。
**接着在Repeat View中选择“First View and Repeat View”**。这是一个很关键的选项。我们知道当使用浏览器访问网站时第一次打开一个新的网页往往会很慢而第二次打开通常就会快很多这是因为浏览器端会缓存很多资源。这个选项的意思就是既要测试第一次打开页面的前端性能First View也要测试在有缓存情况下重复打开的前端性能Repeat View
**最后点击“Start Test”发起测试**。最终的测试设置界面如图1所示。由于全球所有的用户会共享这些散布在各地的测试代理机所以发起测试后一般情况下我们的测试并不会被立即执行而是会进入排队系统。当然WebPagetest界面会清楚地告诉你排在第几位。
![](https://static001.geekbang.org/resource/image/34/76/34dd44a44b1344dfa66ab9f4b6bb6276.png)
图1 WebPagetest的测试执行界面
测试执行完成后我们会看到如图2所示的测试结果页面。这个页面包含非常多的信息接下来我会一一解读这些信息同时跟你分享前端性能指标相关的概念。
![](https://static001.geekbang.org/resource/image/6d/bd/6d886a2474f9dee528ee825574e601bd.png)
图2 WebPagetest的测试结果页面
## 前端性能评估结果评分
图2右上角的性能评估结果栏列出了主要性能评估项目的评分。可以看到“First Byte Time”“Keep-alive Enabled”和“Compress Transfer”三项的评分都是A级说明这三项做得比较好。但是“Compress Images”“Cache static content”和“Effective use of CDN”的评分比较差是需要优化的部分。
那么,接下来我们就看看这六项前端性能指标分别代表什么涵义。
**第一First Byte Time**
First Byte Time指的是用户发起页面请求到接收到服务器返回的第一个字节所花费的时间。这个指标反映了后端服务器处理请求、构建页面并且通过网络返回所花费的时间。
本次测试的结果首次打开页面First View花费的时间是999 ms重复打开页面Repeat View花费的时间是860 ms。这两个指标都在1 s以下所以WebPagetest给出了A级的评分。
**第二Keep-alive Enabled**
页面上的各种资源比如图片、JavaScript、CSS等都需要通过链接Web服务器来一一获取与服务器建立新链接的过程往往比较耗费时间所以理想的做法是尽可能重用已经建立好的链接而避免每次使用都去创建新的链接。
Keep-alive Enabled就是要求每次请求使用已经建立好的链接。它属于服务器上的配置不需要对页面本身进行任何更改启用了Keep-alive通常可以将加载页面的时间减少40%~50页面的请求数越多能够节省的时间就越多。
如图3所示本次测试的结果显示所有的请求都复用了同一个链接所以WebPagetest也给出了A级的评分。
![](https://static001.geekbang.org/resource/image/26/f5/267f522f142b768accbb0d7c5deacaf5.png)
图3 Keep-alive Enabled的统计结果
**第三Compress Transfer**
如果将页面上的各种文本类的资源比如Html、JavaScript、CSS等进行压缩传输将会减少网络传输的数据量同时由于JavaScript和CSS都是页面上最先被加载的部分所以减小这部分的数据量会加快页面的加载速度同时也能缩短First Byte Time。
为文本资源启用压缩通常也是服务器配置更改,无需对页面本身进行任何更改。
如图4所示本次测试结果显示这个网站绝大多数的文本类资源都通过GZip进行了压缩所以WebPagetest也给出了A级的评分。但是第13和第20项的两个资源并没有被压缩报告中显示如果这两个资源也经过压缩将可以减少额外的24.3KB的数据传输量。
![](https://static001.geekbang.org/resource/image/be/d5/be73f00359e0907b4a19c01bb11d9ed5.png)
图4 Compress Transfer的统计结果
**第四Compress Images**
为了减少需要网络传输的数据量图像文件也需要进行压缩处理。显然本次测试结果显示图5所有的JPEG格式图片都没有经过必要的压缩处理并且所有的JPEG格式图片都没有使用渐进式JPEGProgressive JPEG技术所以WebPagetest给出了D级的评分。
如果你不是专门做前端的工程师可能并不知道什么是渐进式JPEG没关系我来简单解释一下吧。
普通JPEG文件存储方式是按从上到下的扫描方式把每一行顺序地保存在JPEG文件中。打开这个文件显示它的内容时数据将按照存储时的顺序从上到下一行一行地被显示直到所有的数据都被读完就完成了整张图片的显示。
如果文件较大或者网络下载速度较慢就会看到图片是被一行一行加载的。为了更好的用户体验渐进式JPEG技术就出现了。
渐进式JPEG包含多次扫描然后将扫描顺序存储在JPEG文件中。打开文件的过程会先显示整个图片的模糊轮廓随着扫描次数的增加图片会变得越来越清晰。这种格式的主要优点是在网络较慢时通过图片轮廓就可以知道正在加载的图片大概是什么。
所以,这种技术往往被一些网站用于打开较大图片。
![](https://static001.geekbang.org/resource/image/cb/4e/cbc6fe30d01bfe4051f2061f9bf12b4e.png)
![](https://static001.geekbang.org/resource/image/ed/05/ed9f9ae7384b0839b44c1d31a4e11705.png)
图5 Compress Images的统计结果
**第五Cache Static Content**
一般情况下页面上的静态资源不会经常变化所以如果你的浏览器可以缓存这些资源那么当重复访问这些页面时就可以从缓存中直接使用已有的副本而不需要每次向Web服务器请求资源。这种做法可以显著提高重复访问页面的性能并减少Web服务器的负载。
如图6所示本次测试结果显示被测网站有超过一半的静态资源没有被浏览器缓存每次都需要从Web服务器端获取所以WebPagetest给出了F级的评分。
![](https://static001.geekbang.org/resource/image/9d/e1/9d24087763ae50ea4ff90a1cd04b7be1.png)
![](https://static001.geekbang.org/resource/image/bf/e8/bfcc9f3aaebd5ec59d711736823124e8.png)
图6 Cache Static Content的统计结果
**第六Effective use of CDN**
首先我来解释一下什么是CDN。
CDN是内容分发网络的缩写其基本原理是采用各种缓存服务器将这些缓存服务器分布到用户访问相对集中的地区的网络供应商机房内当用户访问网站时利用全局负载技术将用户的访问指向距离最近的、工作正常的缓存服务器上由缓存服务器直接响应用户请求。
理解了什么是CDN后我们再一起来看一下本次测试中CDN的使用情况。如图7所示显然本次被测网站绝大多数的资源并没使用CDN。也许是由于本次发起测试的机器是在美国旧金山而旧金山可能并不是该网站的目标市场所以它并没有在这里的CDN上部署资源。
![](https://static001.geekbang.org/resource/image/7b/15/7b7522032fa4996f7c2f76f63c4c1815.png)
图7 CDN使用的统计结果
## 其他前端性能指标解读
![](https://static001.geekbang.org/resource/image/22/c9/228e66ac2fa08026bfaeb3defff139c9.png)
图8 WebPagetest测试显示的前端性能指标
现在我们再回过头来看看如图8所示的表格这个表格包含了很多的前端性能指标大多数指标我们可以从字面上很容易理解其含义比如Load Time、First Byte、Requests等我就不再赘述了。
但是Start Render、First Interactive和Speed Index这三个指标相对较难理解所以我会简单为你解释一下。
**第一Start Render**
Start Render指的是浏览器开始渲染的时间从用户角度看就是在页面上看到第一个内容的时间。该时间决定了用户对页面加载快慢的的第一直观印象这个时间越短用户会感觉页面速度越快这样用户也会有耐心去等待其他内容的展现。如果这个时间过长则用户会在长时间内面对一个空白页面后失去耐心。
理论上讲Start Render时间主要由三部分组成分别是“发起请求到服务器返回第一个字节的时间也就是First Byte时间”“从服务器加载HTML文档的时间”以及“HTML文档头部解析完成所需要的时间”因此**影响Start Render时间的因素就包括服务器响应时间、网络传输时间、HTML文档的大小以及HTML头中的资源使用情况。**
本次测试中第一次打开网页的Start Render时间是5 s而第二次打开网页的Start Render时间是1.83 s。理想的Start Render时间并没有严格的标准一般来情况下这个值最好不要大于3 s所以这个网站还可以再优化一下这个指标。
优化的基本思路是先找出时间到底花在了哪里,由于第二次的结果还是比较理想,所以可以从首次资源加载的角度找出突破口。
**第二First Interactive**
First Interactive可以简单地理解为最早的页面可交互时间。页面中可交互的内容包括很多种类比如点击一个链接、点击一个按钮都属于页面可交互的范畴。First Interactive时间的长短对用户体验的影响十分重要决定着用户对页面功能的使用这个值越短越好。
为了使这个值尽可能得小,我们通常会采取以下措施:
* 只有页面控件内容渲染出来了才有可能进行交互所以First Interactive依赖于Start Render时间。
* 尽量将交互控件的代码放置在HTML BODY的前部让其尽早加载。
* 尽早做JavaScript的初始化和绑定目前大多数做法有两种一是在DOM Ready中做所有JavaScript的初始化和功能绑定二是在页面底部做JavaScript的初始化和功能绑定。
这两种方式的优点在于简单不需要关注具体DOM结点的位置缺点则在于初始化的时间太晚。因此**应该将JavaScript的初始化提前到相关DOM元素建立起来后进行例如将初始化的操作直接放在元素之后进行这样就可以使控件尽可能早地变成可交互状态。**
本次测试中第一次打开网页的First Interactive时间是7.788 s而第二次打开网页的First Interactive时间是略大于1.686 s的某个值。理想的First Interactive时间也没有严格的标准一般情况下这个值最好不要大于5 s所以这个网站还可以根据上面的三条措施再优化一下这个指标。
**第三Speed Index**
严格来说Speed Index是通过微积分定义的。我们理解起来会比较困难所以在这里我们和你只做定性的讨论。
通常影响网页性能体验的一个重要指标是页面打开时间。打开时间越短其体验越好。但是当存在两个打开时间完全相同的网站A和B时其中网站A的打开过程是逐渐渲染页面完成的而网站B的打开过程则是空白了一段时间后在短时间内完成页面渲染完成的。
毫无疑问网站A的用户体验一定好于B。Speed Index就是用来衡量这种体验的通常来讲它的值越小越好。
本次测试中第一次打开网页的Speed Index是8036而第二次打开网页的Speed Index是2373。
## WebPagetest实际使用中需要解决的问题
讨论到这里你是不是觉得WebPagetest是一个很强大的免费工具但是如果想要在实际工程项目中全面推行该工具的话还需要解决两个问题。
**第一个问题是如果被测网站部署在公司内部的网络中那么处于外网的WebPagetest就无法访问这个网站也就无法完成测试**。要解决这个问题你需要在公司内网中搭建自己的私有WebPagetest以及相关的测试发起机。具体如何搭建你可以参考[WebPagetest官网的建议](https://github.com/WPO-Foundation/webpagetest-docs/blob/master/user/Private%20Instances/README.md),这里我就不再继续展开了。
**第二个问题是用WebPagetest执行前端测试时所有的操作都是基于界面操作的不利于与CI/CD的流水线集成**。要解决这个问题就必须引入WebPagetest API Wrapper。
WebPagetest API Wrapper是一款基于Node.js调用了WebPagetest提供的API的命令行工具。也就是说你可以利用这个命令行工具发起基于WebPagetest的前端性能测试这样就可以很方便地与CI/CD流水线集成了。具体的使用步骤如下
1. 通过“npm install webpagetest -g”安装该命令行工具
2. 访问https://www.webpagetest.org/getkey.php获取你的WebPagetest API Key
3. 使用“webpagetest test -k API-KEY 被测页面URL”发起测试该调用是异步操作会立即返回并为你提供一个testId
4. 使用“webpagetest status testId”查询测试是否完成
5. 测试完成后就可以通过“webpagetest results testId”查看测试报告但是你会发现测试报告是个很大的JSON文件可读性较差
6. 通过“npm install webpagetest-mapper -g”安装webpagetest-mapper工具这是为了解决测试报告可读性差的问题将WebPagetest生成的JSON文件格式的测试报告转换成为HTML文件格式
7. 使用“Wptmap -key API-KEY --resultIds testId --output ./test.html”将JSON文件格式的测试结果转换成HTML格式。
## 总结
今天我使用WebPagetest测试了一个具体网站的前端性能。在解读这个测试报告的同时我和你分享了几个重要的前端性能指标以及如何提升这些指标最终达到优化网站用户体验的目的。
虽然WebPagetest是一款免费的、功能强大的前端性能测试工具但是用于实际测试项目时往往还存在两个方面的问题我给你分析了这两个问题出现的原因以及如何解决这两个问题以达到更高效地完成前端性能测试的目的。
## 思考题
除了我今天介绍的WebPagetest外前端测试工具还有YSlow等。你还在工作中接触过哪些前端性能测试工具它们各自有什么特点呢
感谢收听,欢迎你给我留言。