什么是 Web 应用性能评测领域的 RAIL 模型
Measure performance with the RAIL model
RAIL 是一种以用户为中心的性能模型,它提供了一种考虑性能的结构。 该模型将用户体验分解为关键操作(例如,点击、滚动、加载)并帮助您为每个操作定义性能目标。
RAIL 代表 Web 应用程序生命周期的四个不同方面:响应、动画、空闲和加载,即 response, animation, idle 和 load的缩写。用户对这些上下文中的每一个都有不同的性能期望,因此性能目标是根据上下文和用户如何感知延迟的 UX 研究来定义的。
Focus on the user
让用户成为性能工作的焦点。 下表描述了用户如何感知性能延迟的关键指标:
用户对性能延迟的看法
-
0 到 16 毫秒 用户非常擅长跟踪运动,并且不喜欢动画不流畅时的跟踪。 只要每秒渲染 60 个新帧,他们就会认为动画很流畅。 这是每帧 16 毫秒,包括浏览器将新帧绘制到屏幕所需的时间,让应用程序生成一个帧大约需要 10 毫秒。
-
0 到 100 ms 在此时间窗口内响应用户操作,用户感觉结果是立竿见影的。 如果超过这个时延,行动和反应之间的联系就被打破了。
-
100 到 1000 ms 在这个窗口内,事情感觉是任务自然和连续进展的一部分。 对于网络上的大多数用户来说,加载页面或更改视图是一项任务。
-
1000 毫秒或更多 超过 1000 毫秒(1 秒),用户会失去对他们正在执行的任务的注意力。
-
10000 毫秒或更多 超过 10000 毫秒(10 秒),用户感到沮丧并可能放弃任务。 他们以后可能会也可能不会回来。
Goals and guidelines
在 RAIL 的上下文中,术语目标(goals)和指南(guidelines)具有特定含义:
目标:与用户体验相关的关键性能指标。 例如,点击即可在 100 毫秒内渲染。 由于人类的感知是相对恒定的,这些目标不太可能很快改变。
准则:帮助您实现目标的建议。 这些可能特定于当前的硬件和网络连接条件,因此可能会随着时间而改变。
Response: process events in under 50ms
目标:在 100 毫秒内完成由用户输入启动的转换,让用户感觉交互是即时的。
准则:
为确保 100 毫秒内的可见响应,请在 50 毫秒内处理用户输入事件。 这适用于大多数输入,例如单击按钮、切换表单控件或启动动画。 这不适用于触摸拖动或滚动。
尽管这听起来有悖常理,但立即响应用户输入并不总是正确的做法。 您可以使用这个 100 毫秒的窗口来做其他昂贵的工作,但要注意不要阻塞用户。 如果可能,请在后台工作。
对于需要 50 毫秒以上才能完成的操作,请始终提供反馈。
50 ms 还是 100 ms?
目标是在 100 毫秒内响应输入,那么为什么我们的预算只有 50 毫秒? 这是因为除了输入处理之外,通常还有其他工作要做,并且这些工作占用了可接受的输入响应的部分可用时间。 如果应用程序在空闲时间在推荐的 50 毫秒块中执行工作,这意味着如果输入在这些工作块之一期间发生,则它可以排队最多 50 毫秒。 考虑到这一点,可以安全地假设只有剩余的 50 毫秒可用于实际输入处理。下图显示了这种效果,该图显示了在空闲任务期间收到的输入如何排队,从而减少了可用的处理时间:
Animation: produce a frame in 10 ms
目标:
在 10 毫秒或更短的时间内生成动画中的每一帧。 从技术上讲,每帧的最大预算为 16 毫秒(1000 毫秒/每秒 60 帧≈16 毫秒),但浏览器需要大约 6 毫秒来渲染每帧,因此每帧 10 毫秒的准则。
以视觉平滑为目标。 用户会注意到帧速率何时发生变化。
准则:
在像动画这样的高压点中,关键是在你能做的地方什么都不做,在你不能做的地方绝对最少。 尽可能利用 100 毫秒响应预先计算昂贵的工作,以便最大限度地提高达到 60 fps 的机会。
有关各种动画优化策略,请参阅渲染性能。
认识所有类型的动画。 动画不仅仅是花哨的 UI 效果。 这些交互中的每一个都被视为动画:
- 视觉动画,例如入口和出口、补间和加载指示器。
- 滚动。 这包括甩动,即用户开始滚动,然后放手,页面继续滚动。
- 拖拽操作。 动画通常遵循用户交互,例如平移地图或捏合缩放。
Idle: maximize idle time
目标:最大化空闲时间以增加页面在 50 毫秒内响应用户输入的几率。
准则:
利用空闲时间完成延期工作。 例如,对于初始页面加载,加载尽可能少的数据,然后使用空闲时间加载其余的数据。
在 50 毫秒或更短的空闲时间内执行工作。 再这样下去,您就有可能干扰应用程序在 50 毫秒内响应用户输入的能力。
如果用户在空闲时间工作期间与页面交互,则用户交互应始终具有最高优先级并中断空闲时间工作。
Load: deliver content and become interactive in under 5 seconds
当页面加载缓慢时,用户注意力会游移,用户会认为任务已损坏。 加载速度快的网站具有更长的平均会话、更低的跳出率和更高的广告可见度。
目标:
优化与用户的设备和网络功能相关的快速加载性能。 目前,首次加载的一个很好的目标是加载页面并在 5 秒或更短的时间内在 3G 连接速度较慢的中端移动设备上进行交互。
对于后续加载,一个好的目标是在 2 秒内加载页面。
指南:
在您的用户中常见的移动设备和网络连接上测试您的负载性能。 您可以使用 Chrome 用户体验报告来了解您用户的连接分布。 如果数据不适用于您的站点,移动经济 2019 建议良好的全球基线是中端 Android 手机,例如 Moto G4 和慢速 3G 网络(定义为 400 ms RTT 和 400 kbps 传输速度 )。 此组合在 WebPageTest 上可用。
请记住,尽管您的典型移动用户的设备可能声称它使用的是 2G、3G 或 4G 连接,但实际上,由于数据包丢失和网络差异,有效连接速度通常要慢得多。
消除渲染阻塞资源。
您不必在 5 秒内加载所有内容即可产生完整加载的感觉。 考虑延迟加载图像、代码拆分 JavaScript 包以及 web.dev 上建议的其他优化。
认识影响页面加载性能的因素:
- 网络速度和延迟
- 硬件(例如,较慢的 CPU)
- 缓存驱逐(cache eviction)
- L2/L3 缓存的差异
- 解析 JavaScript
Tools for measuring RAIL
有一些工具可以帮助您自动执行 RAIL 测量。 您使用哪一种取决于您需要什么类型的信息,以及您喜欢什么类型的工作流程。
Chrome DevTools
以下 DevTools 功能特别相关:
限制 CPU 以模拟功能较弱的设备
限制网络以模拟较慢的连接
查看主线程活动以查看录制时主线程上发生的每个事件
使用 Main 部分查看页面主线程上发生的活动。
查看表中的主线程活动,以根据占用时间最多的活动对活动进行排序。
记录页面后,您无需仅依赖 Main 部分来分析活动。 DevTools 还提供了三个用于分析活动的表格视图。 每个视图都让您对活动有不同的看法:
- 如果要查看导致最多工作的根活动,请使用“调用树”选项卡。
- 如果要查看直接花费时间最多的活动,请使用自下而上(Bottom-Up)选项卡。
- 如果要按记录期间活动的发生顺序查看活动,请使用“事件日志”选项卡。
分析每秒帧数 (FPS) 以衡量您的动画是否真正流畅地运行
使用性能监视器实时监控 CPU 使用率、JS 堆大小、DOM 节点、每秒布局等
使用“网络”部分可视化录制时发生的网络请求
在录制时捕获屏幕截图以准确回放页面加载时页面的外观,或动画触发等。
查看交互以快速识别用户与其交互后页面上发生的情况
使用交互部分查找和分析录制期间发生的用户交互。
通过在潜在问题侦听器触发时突出显示页面来实时查找滚动性能问题。
实时查看绘制事件以识别可能损害动画性能的代价高昂的绘制事件。
Lighthouse
Lighthouse 可在 Chrome DevTools、web.dev/measure、Chrome 扩展、Node.js 模块和 WebPageTest 中使用。 你给它一个 URL,它模拟一个 3G 连接速度较慢的中端设备,在页面上运行一系列审计,然后给你一份负载性能报告,以及如何改进的建议。
以下审核尤其相关:
response
-
Max Potential First Input Delay:根据主线程空闲时间估计您的应用响应用户输入所需的时间。
-
不使用被动侦听器来提高滚动性能。
-
总阻塞时间。测量页面被阻止响应用户输入(例如鼠标点击、屏幕点击或键盘按下)的总时间。
-
Time To Interactive:衡量用户何时可以始终如一地与所有页面元素进行交互。
Load
不注册控制 page 和 start_url 的 service worker。 Service Worker 可以缓存用户设备上的公共资源,从而减少通过网络获取资源所花费的时间。
移动网络上的页面加载速度不够快。
消除渲染阻塞资源。
推迟屏幕外图像(offscreen images). 推迟加载屏幕外图像,直到需要它们。
适当大小的图像。 不要提供明显大于移动视口中呈现的尺寸的图像。
避免链接关键请求。
不对其所有资源使用 HTTP/2。
有效地编码图像。
启用文本压缩。
避免巨大的网络负载。
避免过大的 DOM 大小。 通过仅传送呈现页面所需的 DOM 节点来减少网络字节。
总结
-
以用户为中心。
-
在 100 毫秒内响应用户输入。
-
动画或滚动时,在 10 毫秒内生成一帧。
-
最大化主线程空闲时间。
-
在 5000 毫秒内加载交互式内容。
更多Jerry的原创文章,尽在:"汪子熙":