Web 性能测试
作为网站应用的开发者或维护者,我们需要时常关注网站当前的健康状况,譬如在主流程运行正常的情况下,各方面性能体验是否满足期望,是否存在改进与提升的空间,如何进行快速且准确的问题定位等,为了满足这些诉求,我们需要进行全面且客观的性能检测。
性能检测的认知
性能检测作为性能优化过程中的一环,它会在检测、记录和改进的迭代过程中不断重复,来协助网站的性能优化不断接近期望的效果。
(1)
不要通过单一指标就能衡量网站的性能体验
。建议从更多维度、更多具体的指标角度来考量网站应用的性能表现,比如页面的首屏渲染时间,不同类型资源的加载次数与速度,缓存的命中率等。
(2)
不要一次检测就能得到网站性能表现的客观结果
。需要在不同时间、不同环境、不同地点下收集尽量多的数据,然后以此来进行性能分析。
(3)
不要仅在开发环境中模拟进行性能检测
。在开发环境中模拟进行的性能检测具有许多优势:比如可以很方便地制定当前检测的设备状况与网络速度,可以对检测结果进行重复调试,但因其所能覆盖的场景有限,会很容易陷入“幸存者偏差”,即所发现的问题可能并非实际的性能瓶颈。
常见的检测工具
- Lighthouse
- WebPageTest
- 浏览器 DevTools - 浏览器任务管理器- Network 面板- Coverage 面板- Memory 面板- Performance 面板- Performance monitor 面板
- 性能监控 API
- 持续的性能监控方案
使用灯塔 Lighthouse 测试性能
Lighthouse 直译过来是“灯塔”的意思,它是由 Google 开发并开源的一个 Web 性能测试工具。该性能检测工具以此命名也蕴涵了相同的含义,即通过监控和检测网站应用的各方面性能表现,来为开发者提供优化用户体验和网站性能的指导建议。直接在F12中就可以测试网站性能。
性能测试代码准备
性能指标
关于性能指标有以下六个关键的数据。
这6种不同的指标数据需要通过加权计算,才能得到关于性能的最终评分,所加的权值越大表示对应指标对性能的影响就越大,如下图所示,列出了目前 Lighthouse 的权重情况。
指标权重FCP10%SI10%LCP25%TTI10%TBT30%CLS15%
该权重系统还在不断优化过程中(最新权重请参考官方),虽然 Lighthouse 对于其中个别指标给予了较大的权重,也就意味着对该指标的优化能够带来更显著的性能评分提升,但这里还要建议在优化的过程中切勿只关注单个指标的优化,而要从整体性能的提升上来考虑优化策略。
优化建议
为了方便开发者更快地进行性能优化,Lighthouse 在给出关键性能指标评分的同时,还提供了一些切实可行的优化建议,如下图所示为检测报告中的优化建议。
这些建议按照优化后预计能带来的提升效果从高到低进行排列,每一项展开又会有更加详细的优化指导建议,从上到下依次包括以下内容。
(1)移除阻塞渲染的资源,部分JavaScript脚本文件和样式表文件可能会阻塞系统对网站页面的首次渲染,建议可将其以内嵌的方式进行引用,并考虑
延迟加载
。报告会将涉及需要优化的资源文件排列在下面,每个文件还包括尺寸大小信息和优化后预计提升首屏渲染时间的效果,据此可安排资源文件优化的优先级。
(2)预连接所要请求的源,提前建立与所要访问资源之间的网络连接,或者加快域名的解析速度都能有效地提高页面的访问性能。这里给出了两种方案:一种是设置〈link rel=“preconnect”〉的
预连接
,另一种是设置〈link rel=“dns-prefetch”〉的
DNS预解析
(3)降低服务器端响应时间,通常引起服务器响应缓慢的原因有很多,因此也有许多改进方法:比如
升级服务器硬件以拥有更多的内存或CPU
,
优化服务器应用程序逻辑以更快地构建出所需的页面或资源
,以及
优化服务器查询数据库
等,不要以为这些可能并非属于前端工程师的工作范围就不去关注,通常node服务器转发层就需要前端工程师进行相应的优化。
(4)适当调整图片大小,使用大小合适的图片可节省网络带宽并缩短加载用时,此处的优化建议通常对于本应使用较小尺寸的图片就可满足需求,但却使用了高分辨率的大图,对此进行适当压缩即可。
(5)移除未使用的CSS,这部分列出了未使用但却被引入的 CSS 文件列表,可以将其删除来降低对网络带宽的消耗,若需要对资源文件的内部代码使用率进行进一步精简删除,则可以使用 Chrome 开发者工具的Coverage面板进行分析。
诊断结果
这部分 Lighthouse 分别从影响网站页面性能的多个主要维度,进行详细检测和分析得到的一些数据,下面我们来对其进行介绍。
(1)对静态资源文件使用高效的缓存策略,这里列出了所有静态资源的文件大小及缓存过期时间,开发者可以根据具体情况进行缓存策略的调整,比如延迟一些静态资源的缓存期限来加快二次访问时的速度。
(2)减少主线程的工作,浏览器渲染进程的主线程通常要处理大量的工作:如解析 HTML 构建 DOM,解析 CSS 样式表文件并应用指定的样式,以及解析和执行 JavaScript 文件,同时还需要处理交互事件,因此渲染进程的主线程过忙很容易导致用户响应延迟的不良体验,Lighthouse 给我们提供了这一环节网站页面主线程对各个任务的执行耗时,让开发者可针对异常处理过程进行有目标的优化,如下图所示。
(3)降低JavaScript脚本执行时间,前端项目的逻辑基本都是依托于JavaScript执行的,所以JavaScript执行效率与耗时也会对页面性能产生不小的影响,通过对这个维度的检测可以发现执行耗时过长的JavaScript文件,进而针对性的优化JavaScript解析、编译和执行的耗时,如图11.20所示。
(4)避免存在较大尺寸网络资源的请求,因为如果一个资源文件尺寸较大,那么浏览器就需要等待其完全加载好后,才能进行后续的渲染操作,这就意味着单个文件的尺寸越大其阻塞渲染流程的时间就可能越长,并且网络传输过程中存在丢包的风险,一旦大文件传输失败,重新传输的成本也会很高,所以应当尽量将较大尺寸的资源进行优化,通常一个尺寸较大的代码文件可以通过构建工具打包成多个尺寸较小的代码包;对于图片文件如非必要还是建议在符合视觉要求的前提下尽量进行压缩。可以看出该检测维度列出的大尺寸资源文件,基本都是图片文件,如图11.21所示。
(5)缩短请求深度,浏览器通常会对同一域名下的并发请求进行限制,超过限制的请求会被暂时挂起,如果请求链的深度过长,则需要加载资源的总尺寸也会越大,这都会对页面渲染性能造成很大影响。因此建议在进行性能检测时,对该维度进行关注和及时优化,如图11.22所示。
已通过的性能
这部分列出的优化项为该网站已通过的性能审核项,对其中重要的几项进行介绍和解读。
(1)延迟加载首屏视窗外的图片,该审核项的优化原理在有关图像优化章节有过详细的介绍,对首屏关键资源加载完毕后,延迟首屏外或处于隐藏状态的图片加载能够有效缩短用户可交互前的等待时间,提升用户访问体验。
(2)压缩 CSS 文件,可降低网络负载规模。
(3)压缩 JavaScript 文件,可降低网络负载规模。
(4)对图片文件采用高效的编码方式,经过编码优化的图片文件,不但其加载速度会更快,而且需要传输的数据规模也会越小,详情可参考图像优化章节的内容。
(5)采用新一代的图片文件格式,WebP、JPEG XR、JPEG 2000等较新的图片文件格式通常比传统的PNG或JPEG有更好的压缩效果,能够获得更快的下载速度和更少的流量消耗,但使用的同时还需要注意对新格式的兼容性处理。
(6)开启文本压缩,对于文本资源,先压缩再提供能够最大限度地减少网络传输的总字节数,常用的压缩方式有 gzip、 deflate 和 brotli,至少采用其中一种即可。
(7)避免多次页面重定向,过多的重定向会在网页加载前造成延迟。
(8)预加载关键请求,通过 来预先获取在网页加载后期需要请求的资源,这主要是为了充分利用网站运行的间歇期。
(9)使用视频格式提供动画内容,建议通过 WebM 或 MPEG4 提供动画,来取代网站页面中大型 GIF 的动画。
(10)避免 DOM 的规模过大,如果 DOM 规模过大,则可能会导致消耗大量的内存空间、过长的样式计算耗时及较高的页面布局重排代价。Lighthouse 给出的参考建议是,页面包含的 DOM 元素最好少于1500个,树的深度尽量控制不要超过32层。
(11)确保在网页字体加载期间文本内容可见,使用 CSS 的 font-display 功能,来让网站页面中的文本在字体加载期间始终可见。
使用 WebPageTest 测试性能
WebPageTest 是一款非常专业的 Web 页面性能分析工具,它可以对检测分析的环境配置进行高度自定义化,内容包括测试节点的
物理位置
、
设备型号
、
浏览器版本
、
网络条件
和
检测次数
等,除此之外,它还提供了目标网站应用于
竞品之间的性能比较
,以及查看网络路由情况等多种维度下的测试工具。
可直接打开 WEBPAGETEST 的主页面,在配置好目标网站应用的网址和检测参数后便可启动测试,等待检测运行结束就能查看详细的测试报告。
使用Chrome DevTools 测试性能
浏览器任务管理器
通过 Chrome 任务管理器我们可以查看当前 Chrome 浏览器中,所有进程关于 GPU、网络和内存空间的使用情况,这些进程包括当前打开的各个页签,安装的各种扩展插件,以及 GPU、网络、渲染等浏览器的默认进程,通过监控这些数据,我们可以在有异于其他进程的大幅开销出现时,去定位到可能存在内存泄漏或网络资源加载异常的问题进程。
Network 网络分析
Network 面板是 Chrome 开发者工具中一个经常会被用到的工具面板,通过它可以查看到网站所有资源的请求情况,包括加载时间、尺寸大小、优先级设置及 HTTP 缓存触发情况等信息,从而帮助我们发现可能由于未进行有效压缩而导致资源尺寸过大的问题,或者未合理配置缓存策略导致二次请求加载时间过长的问题等。
参考:https://developer.chrome.com/docs/devtools/network/。
缓存测试
网络吞吐测试
网络请求阻止
- 打开方式:Ctrl+ Shift + P -> Show Network Request Blocking
- 启用网络请求阻止
覆盖率(Coverage 面板)
我们可以通过 Coverage 面板监控并统计出网站应用运行过程中代码执行的覆盖率情况。该面板统计的对象是 JavaScript 脚本文件与 CSS 样式表文件,统计结果主要包括:每个文件的字节大小、执行过程中已覆盖的代码字节数,以及可视化的覆盖率条形图。
根据执行结果能够发现,在启动录制的过程中到底有哪些尺寸较大的代码文件执行覆盖率较低,这就意味着有些代码文件中可能存在较多的无用代码,更准确地说是暂时没用到的代码。这些信息对性能优化来说是非常有用的,开发者可以据此将执行覆盖率较低的代码文件进行拆分,将首屏渲染阶段暂时不会执行到的代码部分单独打包,仅在需要的时候再去加载。
同时对规模较大且迭代周期较长的项目来说,工程代码中会包含一些永远都不会执行到的代码,而使用 webpack 的 Tree Shaking 仅能根据 export 进行无关联引用,那么此时 Coverage 面板就为优化提供了一条可以尝试的途径。
内存 (Memory 面板)
前端主要使用 JavaScript 代码来处理业务逻辑,所以保证代码在执行过程中内存的良性开销对用户的性能体验来说尤为重要,如果出现内存泄漏,那么就可能会带来网站应用卡顿或崩溃的后果。
为了更细致和准确地监控网站应用当前的内存使用情况,Chrome 浏览器开发者工具提供了 Memory 面板,通过它可以快速生成当前的堆内存快照,或者查看内存随时间的变化情况。据此我们可以查看并发现可能出现内存泄漏的环节,下图是使用 Memory 面板查看堆内存使用快照的情况。
示例代码
FPS 计数器
另一个非常方便的工具是 FPS 计数,可在页面运行时提供对 FPS 的实时估计。
1、选择 Control+Shift+P (Windows、Linux) 或 Command+Shift+P (macOS) 打开命令菜单。
2、在命令菜单中开始键入Rendering,然后选择显示渲染.
3、在呈现工具 中,打开 FPS 指示器。 新的叠加层将显示在视线的右上角。
4、关闭 FPS 计数并选择 Escape 来关闭呈现工具。
打开测试示例:https://googlechrome.github.io/devtools-samples/jank
Performance 面板
使用 Performance 面板主要对网站应用的运行时性能表现进行检测与分析,其可检测的内容不仅包括页面的每秒帧数(FPS)、CPU 的消耗情况和各种请求的时间花费,还能查看页面在前 1ms 与后 1ms 之间网络任务的执行情况等内容。
使用方式
使用方式非常简单,只需要在进行性能检测的网站页面中打开 Chrome 开发者工具的 Performance 面板即可,这里建议在Chrome 浏览器的匿名模式下使用该工具,因为在匿名模式下不会受到既有缓存或其他插件程序等因素的影响,能够给性能检测提供一个相对干净的运行环境。
图中的“启动检测并刷新页面”按钮用来检测页面刷新过程中的性能表现,单击它会首先清空目前已有的检测记录,然后启动检测刷新页面,当页面全部加载完成后自动停止检测。
Performance monitor
虽然使用 Performance 面板来进行检测能够得到较为全面的性能数据,但依然存在两个使用上的问题,即面板信息不够直观和数据的实时性不够强。
为了弥补这两方面的不足,Chrome 从 64 版本开始便在开发者工具中引入了 Performance monitor 面板,通过它让我们可以实时监控网站应用运行过程中,诸如 CPU 占用率、JavaScript 内存使用大小、内存中挂的 DOM 节点数、JavaScript 事件监听次数及页面发生重绘与重排的处理时间等信息。
据此如果我们发现,当与页面的交互过程中出现某项指标有较为陡峭的增长,就意味着可能有影响性能体验的风险存在。
如图所示为 Performance monitor 面板,图中出现的明显波动是执行刷新页面操作所产生的,可观察到 JavaScript 堆内存大小与 DOM 节点数的指标都有一个明显的断崖式下跌,这正是刷新操作清除了原有 DOM 节点后,还未重新渲染出新节点的时间点。刷新后又做了一波代码优化可以看到性能有所提升。而左上角的帧速录frame rate中的红色线条就是丢帧的表现。
性能测量 APIs
- https://developer.mozilla.org/zh-CN/docs/Web/Performance
- https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Using_the_Performance_API
Window.performance
常用性能指标及计算公式
- DNS 解析耗时: domainLookupEnd - domainLookupStart
- TCP 连接耗时: connectEnd - connectStart
- SSL 安全连接耗时: connectEnd - secureConnectionStart
- 网络请求耗时 (TTFB): responseStart - requestStart
- 数据传输耗时: responseEnd - responseStart
- DOM 解析耗时: domInteractive - responseEnd
- 资源加载耗时: loadEventStart - domContentLoadedEventEnd
- First Byte 时间: responseStart - domainLookupStart
- 白屏时间: responseEnd - fetchStart
- 首次可交互时间: domInteractive - fetchStart
- DOM Ready 时间: domContentLoadEventEnd - fetchStart
- 页面完全加载时间: loadEventStart - fetchStart
- HTTP 头部大小: transferSize - encodedBodySize
- 重定向次数:performance.navigation.redirectCount
- 重定向耗时: redirectEnd - redirectStart
性能监控
版权归原作者 鱼泡泡~ 所有, 如有侵权,请联系我们删除。