性能检测概述
- 网站应用的实际性能表现通常是高度可变的,因为它会受到许多因素的影响,比如用户使用的设备状况、当前网络的连接速度等,因此若想通过性能检测来得到较为客观的优化指导,就不能仅依赖一次检测的数据,而需要在不同环境下收集尽量多的数据,然后以此来进行性能分析。
- 若想通过检测来进行有效的性能优化改进,就需要从尽可能多的角度对网站性能表现进行考量,同时保证检测环境的客观多样,能够让分析得出的结果更加贴近真实的性能瓶颈,这无疑会花费大量的时间与精力,所以在进行性能优化之前我们还需要考虑所能投入的优化成本
Lighthouse
是一款用于改进网站应用质量的开源自动化检测工具,我们只需花费五分钟左右的时间,就可以让Lighthouse
为网站应用快速生成一个全方位的检测报告,其内容包括:性能检测、可访问性检测、SEO
检测,以及是否符合PWA
的检测与其他一些是否符合最佳实践的检测- 通过
Chrome
任务管理器我们可以查看当前Chrome
浏览器中,所有进程关于GPU
、网络和内存空间的使用情况,这些进程包括当前打开的各个页签,安装的各种扩展插件,以及GPU
、网络、渲染等浏览器的默认进程,通过监控这些数据,我们可以在有异于其他进程的大幅开销出现时,去定位到可能存在内存泄漏或网络资源加载异常的问题进程
图11.1 Chrome
任务管理器
Network面板
可以查看到网站所有资源的请求情况,包括加载时间、尺寸大小、优先级设置及HTTP
缓存触发情况等信息,从而帮助我们发现可能由于未进行有效压缩而导致资源尺寸过大的问题,或者未合理配置缓存策略导致二次请求加载时间过长的问题等
图11.2 Network
面板
Coverage面板
- 监控并统计出网站应用运行过程中代码执行的覆盖率情况。该面板统计的对象是
JavaScript
脚本文件与CSS
样式表文件,统计结果主要包括:每个文件的字节大小、执行过程中已覆盖的代码字节数,以及可视化的覆盖率条形图。 - 在启动录制的过程中到底有哪些尺寸较大的代码文件执行覆盖率较低,这就意味着有些代码文件中可能存在较多的无用代码,更准确地说是暂时没用到的代码。这些信息对性能优化来说是非常有用的,开发者可以据此将执行覆盖率较低的代码文件进行拆分,将首屏渲染阶段暂时不会执行到的代码部分单独打包,仅在需要的时候再去加载。
- 同时对规模较大且迭代周期较长的项目来说,工程代码中会包含一些永远都不会执行到的代码,而使用
Webpack
的Tree Shaking
仅能根据export
进行无关联引用,那么此时Coverage
面板就为优化提供了一条可以尝试的途径
图11.3 Coverage
面板
Memory面板
前端主要使用JavaScript
代码来处理业务逻辑,所以保证代码在执行过程中内存的良性开销对用户的性能体验来说尤为重要,如果出现内存泄漏,那么就可能会带来网站应用卡顿或崩溃的后通过它可以快速生成当前的堆内存快照,或者查看内存随时间的变化情况。据此我们可以查看并发现可能出现内存泄漏的环节
图11.4 Memory
面板
erformance monitor面板
虽然使用Performance
面板来进行检测能够得到较为全面的性能数据,但依然存在两个使用上的问题,即面板信息不够直观和数据的实时性不够强。为了弥补这两方面的不足,Chrome
从64版本开始便在开发者工具中引入了Performance monitor
面板,通过它让我们可以实时监控网站应用运行过程中,诸如CPU
占用率、JavaScript
内存使用大小、内存中挂的DOM
节点数、JavaScript
事件监听次数及页面发生重绘与重排的处理时间等信息。
图11.6 Performance monitor
面板
PageSpeed Insights
这是Google
官方推出的用于检测网站页面加载性能的自动化工具,它能够针对移动设备和桌面设备分别进行检测并生成相应的优化改进报告
图11.7 PageSpeed Insights
主页面
根据这些指导建议进行改进便能快速提升一定的性能效果,如图11.8所示。但需要说明的是,这个性能得分和检测结果都是根据Lighthouse
分析的实验数据得出
图11.8 PageSpeed Insights
检测结果
WEBPAGETEST
是一款非常专业的Web
页面性能分析工具,它可以对检测分析的环境配置进行高度自定义化,内容包括测试节点的物理位置、设备型号、浏览器版本、网络条件和检测次数等,除此之外,它还提供了目标网站应用于竞品之间的性能比较,以及查看网络路由情况等多种维度下的测试工具
图11.9 WEBPAGETEST
配置页面
WEBPAGETEST
首先会列出几个关键测试维度的性能评价等级,其中包括:是否启用Keep-alive
、图片压缩、静态资源缓存、首字节到达时间、CDN
使用情况等,对于任何得到非A
或B
评价等级的检测维度都需要进行认真分析和优化改进
图11.10 WEBPAGETEST
检测结果
Lighthouse
Lighthouse
提供了三种使用方式,分别是Chrome
扩展程序、Chrome
开发者工具Audits
面板和Nodejs
命令行使用Nodejs
命令行的方式,首先需要通过npm
或yarn
进行Lighthouse
模块包的全局安装,安装命令如下
// npm 安装
npm install -g lighthouse
// yarn 安装
yarn global add lighthouse
安装好后可使用lighthouse
命令生成目标网站性能检测报告
lighthouse https://www.qq.com/ -output-path=./report.html -output html
它带来的好处是能够将原本需要手动处理的检测过程,纳入持续集成的工作范畴中,对网站性能进行周期性自动化检测,并监控检测报告中的关键指标数据,当出现超过阈值的数据时,以邮件或其他通信工具的方式通知开发者及时优化性能指标有以下六个关键的数据:首次内容绘制时间(FCP
)、首次有效绘制时间(FMP
)、速度指数、首次CPU
闲置时间、可交互前的耗时(TTI
)及首次输入延迟(FID
)
图11.16 性能指标评估结果
- (1)首次内容绘制时间,指的是当用户浏览到网站页面后,浏览器首次呈现出
DOM
元素内容所花费的时间,DOM
内容包括文本、图像、SVG
或非空白的〈canvas
〉标签等,但iframe
中的内容绘制并不会考虑在内。对于该性能指标评分的计算方法是这样的:Lighthouse
会根据网站实际的FCP
时间与存档中大量页面的FCP
时间进行对比计算然后得出,例如约有90%的网站能在3s
内完成FCP
的工作,我们目标网站的FCP
时间也是3s
,那么FCP
指标的得分就是90 - (2)首次有效绘制时间,这个指标衡量的是用户看到网站页面主要内容所花费的时间,通常会和首次内容绘制时间在数值上较为接近,但它还包含了
iframe
中内容的渲染绘制。这里需要注意从Lighthouse
6.0版本开始不再推荐使用FMP
指标来进行性能评估,其主要原因是FMP
对页面加载中的细微差别过于敏感 - (3)速度指数,用来衡量页面加载过程中内容可视化显式的速度,即
Lighthouse
会检测并捕获页面加载过程中每一帧之间的视觉变化进度,然后使用Nodejs
的speedline
模块包来生成相应的评估得分 - (4)首次
CPU
闲置时间,指的是从页面加载至主线程静默且可进行交互输入的时间,只需页面处于视窗中的大部分UI
元素能够交互即可,不要求全部元素都可交互。从Lighthouse
6.0版本开始也不建议使用该指标,因为它与接下来将要介绍的可交互前的耗时指标相比,虽然提供了一些额外的衡量信息,但其差异并不足以为此设置两个相似的指标。 - (5)可交互前的耗时,这是一个非常重要的性能指标,如果网站页面通过延迟可交互性为代价,来提高渲染出首屏页面的速度,则可能会造成的结果是:网站页面看似已经准备就绪,但尝试与之交互时,却得不到任何响应的糟糕体验,比如过度延迟了一些
JavaScript
脚本的加载 - (6)首次输入延迟,指的是用户首次与网站页面进行交互开始到浏览器给出实际响应之间的时间。这是一个以用户为中心考量的性能指标,如同
FCP
关注的是网站内容首次被渲染出来的访问体验,FID
关注的是给予用户及时反馈的使用体验,那么确保网站的高响应速度、低交互延迟必然能够给用户留下良好的第一印象,也只有当用户愿意持续浏览网站或重复访问时,网站的价值才能体现出来。6种不同的指标数据需要通过加权计算,才能得到关于性能的最终评分,所加的权值越大表示对应指标对性能的影响就越大
表11.1 性能指标评分加权情况
优化建议
图11.17 性能检测优化建议
按照优化后预计能带来的提升效果从高到低进行排列
- 移除阻塞渲染的资源,部分
JavaScript
脚本文件和样式表文件可能会阻塞系统对网站页面的首次渲染,建议可将其以内嵌的方式进行引用,并考虑延迟加载 - 预连接所要请求的源,提前建立与所要访问资源之间的网络连接,或者加快域名的解析速度都能有效地提高页面的访问性能。这里给出了两种方案:一种是设置〈
link rel
='preconnect
'〉的预连接,另一种是设置〈link rel
='dns-prefetch
'〉的DNS
预解析 - 适当调整图片大小,使用大小合适的图片可节省网络带宽并缩短加载用时,此处的优化建议通常对于本应使用较小尺寸的图片就可满足需求,但却使用了高分辨率的大图,对此进行适当压缩即可。
- 移除未使用的
CSS
,这部分列出了未使用但却被引入的CSS
文件列表,可以将其删除来降低对网络带宽的消耗,若需要对资源文件的内部代码使用率进行进一步精简删除,则可以使用Chrome
开发者工具的Coverage
面板进行分析。 - 对静态资源文件使用高效的缓存策略,这里列出了所有静态资源的文件大小及缓存过期时间,开发者可以根据具体情况进行缓存策略的调整,比如延迟一些静态资源的缓存期限来加快二次访问时的速度
- 减少主线程的工作,浏览器渲染进程的主线程通常要处理大量的工作:如解析
HTML
构建DOM
,解析CSS
样式表文件并应用指定的样式,以及解析和执行JavaScript
文件,同时还需要处理交互事件,因此渲染进程的主线程过忙很容易导致用户响应延迟的不良体验 - 降低
JavaScript
脚本执行时间,前端项目的逻辑基本都是依托于JavaScript
执行的,所以JavaScript
执行效率与耗时也会对页面性能产生不小的影响,通过对这个维度的检测可以发现执行耗时过长的JavaScript
文件,进而针对性的优化JavaScript
解析、编译和执行的耗时 - 避免存在较大尺寸网络资源的请求,因为如果一个资源文件尺寸较大,那么浏览器就需要等待其完全加载好后,才能进行后续的渲染操作,这就意味着单个文件的尺寸越大其阻塞渲染流程的时间就可能越长,并且网络传输过程中存在丢包的风险,一旦大文件传输失败,重新传输的成本也会很高,所以应当尽量将较大尺寸的资源进行优化,通常一个尺寸较大的代码文件可以通过构建工具打包成多个尺寸较小的代码包;对于图片文件如非必要还是建议在符合视觉要求的前提下尽量进行压缩
- 缩短请求深度,浏览器通常会对同一域名下的并发请求进行限制,超过限制的请求会被暂时挂起,如果请求链的深度过长,则需要加载资源的总尺寸也会越大,这都会对页面渲染性能造成很大影响
图11.18 部分静态资源缓存情况
图11.19 渲染进程主线程任务执行耗时
图11.21 大尺寸资源文件
图11.22 关键请求链延迟
最佳实践
- 使用
HTTP
2协议,HTTP
2协议提供了许多HTTP
1.1协议所不具备的新特性,比如二进制分帧层、多路复用及服务器端推送,新特性会带来新的性能提升 - 使用
HTTPS
协议,应尽量使用HTTPS
,即使是那些非敏感数据的网站页面也应如此,它能够有效地防止入侵者对用户信息进行篡改和监听 - 使用被动监听,将触摸事件和鼠标滚轮事件监听器标记为“
passive
”,能够有效提升页面的滚动性能。 - 跨域链接是不安全的,在外部链接中增加
rel=noopener
或rel=noreferrer
来改善性能和防范安全漏洞 - 避免使用
document.write
(),使用document.write
()动态注入的外部脚本,可能会使页面加载延迟数十秒。 - 避免使用具有已知安全漏洞的前端库,一些第三方脚本可能包含已知的安全漏洞,这将会很容易被入侵者识别并利用,
Lighthouse
检测的过程会对此进行排查,同时一些过期废弃的API
也会被排查出来 - 在浏览器控制台中没有错误的日志信息,打印在浏览器控制台上的错误日志表示网站应用存在未解决的问题,它们可能来自网络请求失败或一些其他浏览器异常,不管怎样都不应对此熟视无睹。
图11.25 最佳实践审核项
Performance面板的使用
Performance面板的使用
- 使用
Performance
面板主要对网站应用的运行时性能表现进行检测与分析,其可检测的内容不仅包括页面的每秒帧数(FPS
)、CPU
的消耗情况和各种请求的时间花费,还能查看页面在前1ms
与后1ms
之间网络任务的执行情况。为了降低读者理解与使用的成本 - 只需要在进行性能检测的网站页面中打开
Chrome
开发者工具的Performance
面板即可 - 建议在
Chrome
浏览器的匿名模式下使用该工具,因为在匿名模式下不会受到既有缓存或其他插件程序等因素的影响,能够给性能检测提供一个相对干净的运行环境。 - 当我们需要检测一段时间内的性能状况时,可单击两次“启动/停止检测”按钮来设置起止时间点,当单击第二次按钮停止检测后,相应的检测信息便出现在控制面板下方的区域。
- “启动检测并刷新页面”按钮用来检测页面刷新过程中的性能表现,单击它会首先清空目前已有的检测记录,然后启动检测刷新页面,当页面全部加载完成后自动停止检测。
Performance
的评估结果页,如图11.29所示,其中的面板信息大致可分为四大类:控制面板、概览面板、线程面板及统计面板
图11.29 Performance
的评估结果页
控制面板
Screenshots
:表示是否截取每一帧的屏幕截图,默认会勾选,并且在概览面板中展示随时间变化的每帧截屏画面,如果取消勾选,则不会在概览面板中展示这部分内容Disable javaScript samples
:如果勾选则表示关闭JavaScript
样本,减少在手机端运行时的开销,若要模拟手机端的运行环境时则需要勾选。Network
:在性能检测时,用以切换模拟网络环境CPU
:限制CPU
处理速度,主要用于模拟低速CPU
运行时的性能
概览面板
通过选择一个起始时间点,然后按住鼠标左键滑动选择面板中的局部范围,来进行更小范围内的性能观察对每秒帧数而言,尽量保持在60FPS
才能让动画有比较流畅的视觉体验。对网络请求时间而言,概览面板提供的信息可能不够清晰,这里建议在线程面板的Network
部分中具体查看,比如时间轴上每个请求的耗时及起止时间点都会更加清楚,从而方便开发者发现响应过长的网络请求并进行优化
线程面板
线程执行过程的火焰图,主线程在解析HTML
和CSS
、页面绘制及执行JavaScript
的过程中,每个事件调用堆栈和耗时的情况都会反映在这张图上,其中每一个长条都代表了一个事件,将鼠标悬浮其上的时候可以查看到相应事件的执行耗时与事件名
图11.32 线程面板中事件执行的火焰图