续接 性能测试概论(一)。
04. 全链路性能测试
前面提到,性能主要包含时间和资源两个指标。为了继续说明问题,以一次 Web 访问为例(比如在浏览器中输入 www.test.com),来看看其中到底发生了什么(这也是一道经典的面试题)。
首先由 DNS 服务器将域名解析为 IP 地址,而后客户端(浏览器)与该 IP (服务端)建立 TCP 连接。连接成功之后,客户端开始向服务端发送请求。服务端通常拥有一个网关,将请求动态分派至集群中的某个服务器。服务器接收到请求,执行相应的代码逻辑,并从数据库中获取数据,经过加工处理之后返回内容至客户端。
如果返回的是一个 HTML 文档,客户端往往还需要进一步下载 JS、CSS 以及图片等静态资源,以便完成对整个页面的渲染;如果是一个仅用于更新部分数据的异步请求,客户端一般也会进行局部区块的更新和渲染。待以上步骤全部完成之后,这次访问才算是真正结束。整个过程的性能表现可以分成两个部分:前端和后端。前端从客户端接收服务端的返回开始,至页面渲染完成结束;后端从客户端提交请求开始,至服务端返回内容结束。注意这里有个陷阱是,后端并非是从接收客户端请求开始的,因为还包含前面的网络时间。
前端和后端的性能测试有一个重大区别:前端性能与单个客户端相关,不需要考虑并发问题;而后端是共享资源,需要模拟多用户的状况。所以后端的性能场景设计和性能分析,往往比前端要复杂很多。不过我们在做性能测试的时候,可以独立进行前端或后端的验证,以此降低问题的复杂度。
虽然我们在提到性能的时候,经常把注意力放在了后端性能上,但从用户侧来看,性能是指端到端的表现,所以前端性能和后端性能同样重要。所谓的全链路性能测试,即指从客户端到服务端的完整链路测试,包括前端界面、网关、后端服务、中间件、数据库等,模拟了真实的用户访问场景。
全链路性能测试算不上是新的技术,应该说是一种新的方案。以往的单模块(单链路)、基于测试环境或拟真环境的性能测试方案,或多或少都会与生产环境的真实情况有所差异,导致性能测试结果的参考意义比较有限。所以全链路性能是一种基于生产环境、完整业务链、接近真实流量和数据的性能测试解决方案。
05. Web 性能评测
开篇的时候讲过,性能在一定程度上是个体验问题。所以 Web 的性能表现,并不是以页面完成全部渲染的时间来衡量的。那么又该如何去评价 Web 的性能呢?其实并没有一个“唯一”指标能够全面代表,我们需要从多个维度去做一个综合评价。比如以下常见指标:
- FP(First Paint):首次绘制时间,即屏幕上开始渲染画面像素的起始时间。
- FCP(First Contentful Paint):首次内容绘制,与 FP 的区别是绘制的是内容,比如文本、图片。
- FMP(Fist Meaningful Paint):首次有效绘制,有效指根据某种算法定义的主要内容区块。
- LCP(Largest Contentful Paint):最大内容绘制,最大的可视区块开始出现的起始时间。
FP 和 FCP 表示的是屏幕开始出现视觉变化的时间点,而 FMP 和 LCP 表示的是屏幕开始出现对用户“有意义”内容的时间点。有些情况下,Web 性能会以 FMP 或 LCP 来做评估。当然了,这不是硬性规定,开发者可以自行决定和通过埋点上报当页面加载到何种程度时,我们认为自己的应用已经达到“可用”状态。
有许多工具可以用于评测 Web 性能,比如 Lighthouse、WebPageTest 等,甚至也可以使用 Chrome 自带的 DevTools 性能分析器。这些工具除了帮助我们得到一些指标值,还可以获得关于如何优化该指标的建议。以 Lighthouse 为例,报告给到了性能的评分、FCP/LCP 的值以及多项优化措施建议。
此外,图中还可以看到另外几个指标值:Total Blocking Time(TBT)、Cumulative Layout Shift(CLS) 以及 Speed Index。TBT 指的是页面不可交互时间,对响应有要求的应用具有重要参考;CLS 指的是页面的累计布局偏移,用于衡量页面的稳定性;Speed Index 则是一个综合指标,表示用户感受到的加载速度。
这些指标主要来自 Google Web Vitals。Google 提出了三个主要用户体验衡量指标:LCP、FID 和 CLS(FID 需要交互,静态检查下用了 TBT 作为替代),感兴趣的小伙伴可以自行学习。相似的,多年前 Yahoo 也提出过 Web 优化的 23 条军规,流浏览器有个 YSlow 插件即是基于这些规则做出性能评价。
Google 和 Yahoo 提出的是一些“最佳实践”,这些实践因为具备较好的参考价值而被广泛采纳,但并不意味着它们是需要被 100% 遵守的,这点需要辨明。另外,因为 Web 端的资源类指标(比如耗电等)在 PC 场景下相对不那么重要(个别时候也会有),所以这一节中也就未涉及关于资源指标的评测内容。
06. Web 性能优化
Web 的性能优化大致上可以从这几个方向去考虑:加载时序、请求数量、资源大小、缓存技术。
1)加载时序
加载时序的策略是,通过改变信息的加载顺序,来达到优化关键指标(FMP)的目的。比如常见的将 CSS 置于顶部(CSS 包含样式信息),以减少用户可见内容的渲染时间;以及将 JS 置于底部(JS 会阻断页面渲染),以避免加载过程出现“白屏”或“中断”。
分步加载也是常用的方式。比如页面上有张图片较大,加载时间可能较长,那么可以预先生成较小的缩略图,在访问页面时先加载缩略图,而后“慢慢”下载原始图片,待完成之后再替换掉缩略图。这种方式通过在视觉上的快速反馈,来达到更好的性能体验,类似的方法还有 Loading 图标、骨架屏等。
还有一种重要技术是延迟加载(Lazy load,也称懒加载)。比如页面的篇幅比较长,需要上下滚动屏幕才能完整查看,那么当访问页面时,只需要加载首屏内容即可,非可见区域的资源可以暂时不予下载,以节省时间和资源。延迟加载技术对移动端应用的作用尤为明显,为用户节约了大量的宝贵流量。
2)请求数量
在一次 HTTP 请求里,会有两个方面影响到性能:第一个是通信消耗的时间,包括域名解析、网络传输、TCP 连接等耗时;第二个是请求、响应本身会携带一些头信息,数量多了以后也会造成不必要的消耗。所以在成本可控的情况下,应当尽量减少 HTTP 的总体请求数。
我们一般通过合并同类资源的方式来达到这个目的。比如页面上存在很多小图标,那么可以把这些图标都放在一张图片上,通过 CSS Sprite 获取所需的图片区域,类似的还有合并 CSS、JS 等。不过也有观点认为,在当前的网络环境下,请求数量对整体性能的影响并不大,这点也就没有那么被重视了。
3)资源大小
GZIP 是最常用的一种 Web 资源压缩技术,通常可以拥有 3~10 倍的压缩比率,大幅减少传输所用的带宽和时间。GZIP 多用于 HTML、CSS 和 JS 的压缩,对图片的作用比较有限。原因是 GZIP 所采用的算法,更适用于重复度比较高(比如文本)的内容,但是图片的重复度往往不大。
另外一种压缩方法是去除 CSS 以及 JS 文件中的空格(空格并不影响脚本执行),也可以在一定程度上减少这两类文件的体积,这就是为什么我们在生产环境查看 CSS、JS 的时候,它们的文本“糊”在一起的原因。现在的很多前端构建工具(比如 Webpack)都可以支持去除空格的操作。
4)缓存技术
浏览器本身默认会对静态资源进行缓存。客户端识别响应头中的 Expires 和 Cache-Control 等信息,来决定要使用缓存中的资源或是重新从服务端获取。我们在浏览器中使用 Ctrl + F5,即是在要求浏览器强制更新所有资源。浏览器的静态资源缓存机制实际还比这复杂很多,这里不做扩展。
CDN(内容分发网络)也可以算是某类“缓存”机制。它的基本原理是,将静态资源分发到多个区域的节点上,当用户请求这些资源时,CDN 可以根据各个节点的负载、与用户的距离等因素,实时将请求定向到离用户最近(最快)的一个节点上,以提高用户访问的整体速度。
(未完待续…)
声明:文中观点不代表本站立场。本文传送门:https://eyangzhen.com/416584.html