用户会注意到网站和应用是否运行不畅,因此优化渲染性能至关重要!
当今网络的用户希望他们访问的网页具有互动性和流畅性,这也是您需要越来越多地投入时间和精力的地方。 网页不仅应快速加载,还应在整个生命周期内快速响应用户输入。事实上,Interaction to Next Paint (INP) 指标衡量的正是用户体验的这一方面。INP 良好意味着网页能够持续可靠地响应用户的需求。
虽然让网页感觉快速的主要因素涉及您为响应用户互动而执行的 JavaScript 量,但用户期待的是界面的视觉变化。界面视觉变化是多种类型工作的结果,这些工作通常统称为渲染,需要尽快完成,以便让用户体验感觉快速可靠。
若要编写能够快速响应用户互动的网页,您需要了解浏览器如何处理 HTML、JavaScript 和 CSS,并确保您编写的代码以及您添加的任何其他第三方代码尽可能高效地运行。
关于设备刷新率的说明
现在,大多数设备每秒刷新屏幕 60 次。每次刷新都会产生您看到的视觉输出,通常称为“帧”。以下视频演示了帧的概念:
虽然设备的屏幕始终以一致的速率刷新,但在设备上运行的应用不一定始终能够生成足够的帧来匹配该刷新率。例如,如果有动画或过渡效果正在运行,浏览器需要与设备的刷新率保持一致,以便在每次屏幕刷新时生成一帧。
鉴于典型显示屏每秒刷新 60 次,通过简单的数学计算,我们可以得出浏览器有 16.66 毫秒的时间来生成每一帧。 但实际上,浏览器对每一帧都有自己的开销,因此您需要在 10 毫秒内完成所有工作。如果您未能满足此预算,帧速率就会下降,页面内容会在屏幕上抖动。这种现象通常称为卡顿。
不过,您的目标会根据您尝试执行的工作类型而变化。对于动画,达到 10 毫秒阈值至关重要,因为屏幕上的对象会在两个点之间的一系列帧中进行插值。对于界面中的离散变化(即从一种状态过渡到另一种状态,中间没有任何运动),建议您在用户感觉瞬间完成的时间范围内实现此类变化。在这种情况下,100 毫秒是一个经常被引用的数字,但 INP 指标的“良好”阈值为 200 毫秒或更短,以便适应具有不同功能的更广泛设备。
无论您的目标是什么(是生成动画所需的许多帧以避免卡顿,还是仅仅尽快在界面中产生离散的视觉变化),了解浏览器的像素管道的工作原理对您的工作都至关重要。
像素流水线
在 Web 开发者工作中,您需要了解并注意五个主要方面。这五个方面是您最能掌控的,每个方面都代表了像素到屏幕流水线中的一个关键点:
- JavaScript:JavaScript 通常用于处理会导致界面发生视觉变化的工作。例如,这可能是 jQuery 的
animate函数、对数据集进行排序或向页面添加 DOM 元素。 不过,JavaScript 并非触发视觉变化的必要条件:CSS 动画、CSS 过渡和 Web Animations API 都可以为网页内容添加动画效果。 - 样式计算:此过程会根据匹配的选择器,确定哪些 CSS 规则适用于哪些 HTML 元素。例如,
.headline是一个 CSS 选择器示例,它适用于任何class属性值包含headline类的 HTML 元素。然后,一旦知道规则,就会应用这些规则,并计算每个元素的最终样式。 - 布局:浏览器知道哪些规则适用于元素后,就可以开始计算网页的几何形状,例如元素占用的空间大小以及它们在屏幕上的显示位置。Web 的布局模型意味着一个元素可能会影响其他元素。例如,
<body>元素的宽度通常会影响其子元素在树中上下移动的尺寸,因此浏览器可能需要执行相当复杂的流程。 - 绘制:绘制是填充像素的过程。它涉及在计算出元素在网页上的布局后,绘制出文本、颜色、图片、边框、阴影以及元素的每个视觉方面。 绘制通常在多个 Surface(通常称为层)上完成。
- 合成:由于网页的各个部分可能绘制在多个图层上,因此需要按正确的顺序将它们应用到屏幕上,以便网页按预期呈现。这对于相互重叠的元素尤为重要,因为错误可能会导致一个元素错误地显示在另一个元素的顶部。
像素流水线的每个部分都可能导致动画卡顿,或者延迟帧的绘制,即使是用户界面发生离散的视觉变化也是如此。因此,请务必确切了解您的代码会触发流水线的哪些部分,并调查是否可以将更改限制在渲染这些更改所需的像素流水线部分。
您可能听说过“光栅化”一词与“绘制”结合使用。这是因为绘制实际上包含两项任务:
- 创建绘制调用列表。
- 正在填充像素。
后者称为“光栅化”,因此,每当您在开发者工具中看到绘制记录时,都应将其视为包含光栅化。在某些架构中,创建绘制调用列表和光栅化是在不同的线程上完成的,但作为开发者,您无法控制这一点。
您不一定会在每一帧上都触及流水线的每个部分。 事实上,当您使用 JavaScript、CSS 或 Web Animations API 进行视觉更改时,对于给定的帧,流水线通常有三种执行方式。
1. JS/CSS > 样式 > 布局 > 绘制 > 合成
如果您更改“布局”属性,例如更改元素的几何图形(如宽度、高度或其位置,例如 left 或 top CSS 属性),浏览器需要检查所有其他元素并“重排”页面。任何受影响的区域都需要重新绘制,并且最终绘制的元素需要重新合成。
2. JS/CSS > 样式 > 绘制 > 合成
如果您在 CSS 中更改了元素的“仅绘制”属性(例如 background-image、color 或 box-shadow 等属性),则无需执行布局步骤即可向网页提交视觉更新。通过尽可能省略布局步骤,您可以避免可能耗费大量资源的布局工作,否则这些工作可能会在生成下一帧时造成严重的延迟。
3. JS/CSS > 样式 > 复合
如果您更改了既不需要布局也不需要绘制的属性,浏览器可以直接跳到合成步骤。对于页面生命周期中的高压力点(例如动画或滚动),这是通过像素管道的最廉价、最理想的路径。有趣的事实:Chromium 会优化页面的滚动,以便尽可能仅在合成器线程上进行滚动,这意味着即使页面没有响应,您仍然可以滚动页面并查看之前绘制到屏幕上的部分。
Web 性能是一门避免工作的艺术,同时尽可能提高任何必要工作的效率。在许多情况下,这涉及与浏览器协作,而不是与其对抗。值得注意的是,之前在流水线中显示的工作在计算成本方面有所不同;有些任务本质上比其他任务更昂贵!
我们来深入了解一下流水线的不同部分。我们将探讨常见问题,以及如何诊断和解决这些问题。
浏览器渲染优化
性能对用户来说至关重要,为了打造良好的用户体验,Web 开发者需要构建能够快速响应用户互动并流畅渲染的网站。性能专家 Paul Lewis 将帮助您消除卡顿,打造能够保持每秒帧数 60 的 Web 应用。学完本课程后,您将掌握分析应用和找出导致渲染性能不佳的原因所需的工具。您还将探索浏览器的渲染流水线,并发现一些模式,以便更轻松地构建让用户感到愉悦的快速网站。