前端静径

网页性能分析不完全指南

前言

经常能在博客或者论坛上看到很多有关前端性能优化的文章,但是却很少看到如何分析一个网页的性能的文章。到底什么样的指标(或者说是标准)代表这个网页性能好或者不好,通过什么方式来得到这些指标呢?因此,本文来讲述下如何分析一个网页的性能的好与差。本文用到的工具:chrome浏览器。下面我们一一来看。

用RAIL模型评估运行时性能

首先要说明的是,运行性能是指你的网页在运行的时候的性能,而不是加载的时候的性能。RAIL(Response-Animation-Idle-Load)模型是一种以用户为中心的性能模型,每个网络应用均具有与其生命周期相关的四个不同方面,且这些方面以不同的方式影响着性能。用官网图来镇压一下:

alt RAIL模型

下面分别从四个方面阐述RAIL模型:

以用户为中心

任何网站的终极目标不是让其在任何特定设备上都能运行很快,而是让使用该网站的用户满意。用户花在网站上的大多数时间不是等待加载,而是在使用过程中等待响应。那么怎样评价延迟?让我们来看下面的表:

延迟 用户反应
0~16毫秒 人们特别擅长跟踪运动,如果动画不流畅,他们就会对运动心生反感。 用户可以感知每秒渲染60帧的平滑动画转场,也就是每帧16毫秒(包括浏览器将新帧绘制到屏幕上所需的时间),那么,留给应用大约只有10毫秒的时间来生成新帧。
0~100毫秒 在此时间内响应用户操作,他们会觉得可以立即获得结果。时间再长,操作与反应之间的连接就会中断
100~300毫秒 用户会遇到轻微可觉察的延迟。
300~1000毫秒 在此时间内,延迟感觉像是任务自然和持续发展的一部分。对于网络上的大多数用户,加载页面或更改视图就像在完成一个任务。
1000+毫秒 超过1秒,用户的注意力将离开他们正在执行的任务。
10,000+毫秒 用户感到失望,可能会放弃任务,并且之后他们或许不会再回来。

响应(Response): 在100毫秒以内响应

在用户注意到滞后之前网站有100毫秒的时间可以响应用户输入。这适用于大多数输入,比如点击按钮、切换表单控件或是启动动画。但是不适用于触摸拖动或滚动(因为触摸拖动或滚动属于动画范畴)。如果网站未响应,操作与反应之间的连接就会中断,用户会注意到。因此,对于需要超过500毫秒才能完成的操作,需要始终提供反馈。

其实,有些动作可以不等到用户操作了才响应。网站可以使用此100毫秒时间在后台来执行其他开销大的工作,但前提是不影响用户当前的操作。

动画(Animation): 在10毫秒内生成一帧(即达到60fps)

动画不止是奇特的UI效果,例如滚动和触摸拖动也属于动画类型。如果动画帧率发生变化,用户便会注意到。网站的目标是每秒生成60帧,每一帧必须完成以下所有步骤:

alt 渲染步骤

从纯粹的数学角度而言,每帧的预算约为16毫秒(1000毫秒/60帧=16.66毫秒/帧)。但将新帧渲染到屏幕上也是需要花费时间的,因此实际上浏览器只有10毫秒的时间来执行代码,如果无法符合此估算,帧率将下降,并且内容会在屏幕上抖动,也就是卡顿,会对用户体验产生负面影响。因此,如果可能,最好利用好100毫秒响应预先计算开销大的工作,这样网站就更有可能实现60fps的性能。

空闲(Idle):最大程度增加空闲时间

可以利用空闲来完成推迟的工作。例如:尽可能减少预加载的数据,以便网站能够快速加载,并利用空闲时间加载剩余数据。推迟的工作应分成每个耗时约50毫秒的多个块。如果用户开始交互,优先级最高的事项是响应用户。要实现小于100毫秒的响应,应用必须在每50毫秒内将控制返回给主线程,这样网站就可以执行其他像素管道、对用户输入作出反应等命令。

因此,以50毫秒块工作既可以完成任务,又能确保即时的响应。

加载(Load):在1000毫秒以内呈现内容

在1秒钟内加载网站,否则,用户的注意力会分散,他们处理任务的感觉会中断。其实也无需在1秒内加载所有内容以让用户产生完整加载的感觉。应该启用渐进式渲染和在后台执行一些工作,将非必需的加载推迟到空闲时间段再来加载。

关键RAIL指标汇总

要根据RAIL指标评估您的网站,可使用Chrome的DevTools的performance面板(旧版本chrome可以用TimeLine工具)记录用户操作(具体可见下面一节讲解如何记录性能数据)。然后根据这些关键RAIL指标检查面板中的记录时间。

RAIL步骤 关键指标 用户操作
响应 输入延迟时间(从点按到绘制)小于100毫秒。 用户点按按钮(例如打开导航)。
动画 每个帧的工作(从JS到绘制)完成时间小于16毫秒。 用户滚动页面,拖动手指(例如打开菜单)或看到动画。 拖动时,应用的响应与手指位置有关(例如,拉动刷新、滑动轮播)。 此指标仅适用于拖动的持续阶段,不适用于开始阶段。
空闲 主线程JS工作分成不大于50毫秒的块。 用户没有与页面交互,但主线程应足够用于处理下一个用户输入。
加载 页面可以在1000毫秒内就绪。 用户加载页面并看到关键路径内容。

利用chrome开发者工具执行运行时性能评估

下面的教程指引了如何利用chrome开发车工具(DevTools)的performance面板来分析运行时性能。

注意:下面的指引基于chrome 62版本,如果你用了其他版本的chrome,其UI界面和特征会有些许的不同。

准备工作

首先我们打开官网提供的demo,请确保用浏览器隐身模式打开,以保证浏览器是在一个纯净的环境中。否则,如果你安装了很多浏览器扩展,会对你性能分析的数据产生一定的干扰。接着打开DevTools,具体方法:Command+Option+I (Mac) or Control+Shift+I (Windows, Linux)

alt 图示

模拟手机CPU

手机设备具有比台式机和笔记本更小的CPU频率,无论何时评估你的网页,你都必须使用CPU限制来模拟网页在手机设备上表现。

  1. 在DevTools中,点击Performance面板
  2. 确保Screenshots复选框选中
  3. 点击Capture Settings(右上角的红色设置图标),展开其他设置
  4. CPU中选择4x slowdown,DevTools会将CPU频率限制到平时的四分之一。

alt 图示

注意:如果测试其他页面,如果想测试在低端机上的性能,可以选择更低的倍数。这个只是为了更好的演示,选择了小一点的限制。

设置demo

  1. 连续点击Add 10按钮,知道明显能看到蓝色方框比之前慢了,在高端机上可能要点击20次左右。
  2. 点击Optimize按钮,蓝色方框应该移动地更快更平稳。
  3. 点击Un-Optimize按钮,蓝色的方块移动得更慢更松弛。

    注意:如果你没有观察到明显变慢,尝试点击几次Subtract 10按钮再尝试前面步骤。否则如果你添加了太多的蓝色方框,就会耗尽CPU资源。

记录运行性能

当你页面运行网页的优化版本,蓝色方框移动速度会变快。为了更好的检测出性能问题,我们记录网页非优化的版本。

alt 图示

  1. 点击Record按钮(见图示),DevTools会在页面运行时捕获性能指标。
  2. 等待几秒钟
  3. 点击Stop按钮(见图示),DevTools停止记录,并开始处理数据,随后将处理结果显示在performance面板中,如下图

alt 图示

分析结果

关键的性能指标是FPS,其值如果是60FPS,用户体验会很好,使用网站的感受也是愉悦的。

FPS图表

查看FPS图表(图中蓝色方框框住的部分),如果看到了红色长条,就代表帧率太低并已经影响到用户体验了。一般情况下,绿色长条越高,FPS越高。

alt 图示

CPU图表

在FPS下面就是CPU图表,图表中的颜色和面板底部的Summarytab中的颜色是匹配的。CPU颜色越丰富,代表在录制过程中CPU已经最大化了。如果这段丰富颜色的长条比较长,这就暗示网站应该想办法让CPU做更少的工作了,也就是说代码逻辑需要做优化了。

alt 图示

顺便提一下的就是,无论鼠标移动到FPS,CPU或者NET图表上,DevTools都会显示在该时间节点上的屏幕截图,将你的鼠标左右移动,可以重放录制画面,这被称为擦洗,对于手动分析动画进程很有用。

alt 图示

Frames部分

在Frames部分,如果将你的鼠标移动至绿色方块部分,会显示在该特定帧上的FPS值,此例中每帧可能远低于60FPS的目标。的确,在这个例子中,这个页面的性能很差并且能很明显地被观察到,但是在实际场景中,可能并不是那么的容易,所以,要用所有这些工具来进行综合测量。

alt 图示

寻找瓶颈(追根溯源)

现在你已经通过上面的各种方式了解并确信了这个网页的性能不好,那么为什么会差呢?是什么导致它运行的这么差的呢?

Summary Tab

当没有选择任何事件的时候,Summary tab显示了网页进程活动的分类。从图中可以看出,这个网页花费了太多的时间在渲染(rendering)上了。因此,你的目标就是减少渲染工作花费的时间。

alt 图示

Main部分

展开Main部分,DevTools将显示主线程上的随着时间推移的活动火焰图。x轴代表随时间推移的记录,每个长条代表一个事件,长条越宽,代表这个事件花费的时间越长。y轴代表调用堆栈,当你看到堆叠在一起的事件时,意味着上层事件发起了下层事件。

alt 图示

可以通过单击、鼠标滚动或者拖动来选中FPS,CPU或NET图标中的一部分,Main部分和Summary Tab就会只显示选中部分的录制信息。注意Animation Frame Fired事件右上角的红色三角形图标,该红色三角图标是这个事件有问题的警告。

单击Animation Frame Fired事件,Summary tab会显示该事件相关的信息。

alt 图示

注意reveal,点击它,会高亮触发Animation Frame Fired事件的事件。

alt 图示

注意app.js:95,点击它,会跳转到source面板对应的源码及其对应的行号。

当选中了一个事件之后,可以使用键盘上的箭头来选择前面或者后面的事件

Animation Frame Fired事件下面有一群紫色的事件。如果把它们放宽一点,会看到几乎每个紫色事件的右上角都有红色三角形图标。点击其中一个紫色事件(其实就是Layout事件),Summary tab会显示该事件更详细的信息。确实,这里有一个强制reflow的警告。

alt 图示

在Summary tab,点击Recalculation Forced下面的app.js:71,DevTools会跳转到触发强制reflow的代码行。

alt 图示

这个代码的问题在于,在动画的每一帧都改变了蓝色方块的样式并计算了每个方块在页面的位置。因为样式改变了,浏览器却不确定是否是每一个方块的位置都改变了,因此浏览器为了计算方块的位置,只能对方块重新布局。可以查看Avoid forced synchronous layouts这篇文来了解如何避免大型、复杂的布局和布局抖动。

更多的时间线事件参考,请点击这里

利用chrome开发者工具执行加载性能评估

  1. 打开你要评估的页面
  2. 打开performance面板
  3. 点击Start profiling and reload page(图中蓝色方框框住部分),DevTools在页面重新加载时记录性能指标,然后在加载完成后几秒钟自动停止录制。
  4. 其他分析方式同上面的运行时性能评估。

alt 图示

如同评估运行时性能一样设置了CPU限制,你也可以在设置里面设置network控制,来调整你想要的网络速度环境。

总结

可以使用chrome浏览器DevTools中的Performance面板来得到网页的加载性能和运行时的性能数据,根据上文介绍的分析方法,结合RAIL模型来评估网页性能的好与差。这是一个很有效的方法。具体如何提高网页的性能呢?这又是一个大课题,相信网上也有不少与之相关的博文可以参考,笔者后续有时间也出相关博文。

参考文献

Get Started With Analyzing Runtime Performance