为下一代网页内容做好准备
RenderingNG 是新一代渲染架构,性能大大优于之前的架构。RenderingNG 已构建超过八年之久,代表了众多专业 Chromium 开发者的集体成果。它为快速、流畅、可靠、响应迅速的交互式 Web 内容释放了巨大的潜力。
在这里,您将了解我们开发这款应用、推出这款应用的原因和运作方式。
北极星目标
RenderingNG 的动力是浏览器引擎实现及其渲染 API 的丰富性不应成为 Web 用户体验的限制因素。
您无需担心浏览器 bug 会使功能不可靠,或破坏网站的呈现。
游戏不应出现神秘的性能悬崖。 此外,您应该无需解决缺少内置功能的问题。
它应该可以正常使用。
RenderingNG 朝着这个北极星目标迈出了一大步。在 RenderingNG 之前,我们可以(并且已经)添加渲染功能并提升性能,但很难使这些功能对开发者而言可靠,并且存在许多性能悬崖。现在,我们的架构可以系统地解决其中许多问题,同时解锁以前不可行的高级功能。它:
- 具备强劲的核心功能,覆盖不同的平台、设备和操作系统组合。
- 具有可预测且可靠的性能。
- 最大限度地利用硬件功能(核心、GPU、屏幕分辨率、刷新率、低级别光栅 API)。
- 仅执行显示可见内容所需的工作。
- 本身就支持常见的视觉设计、动画和互动设计模式。
- 提供开发者 API 以轻松管理渲染成本。
- 为开发者插件提供渲染流水线扩展点。
- 优化所有内容 - HTML、CSS、2D 画布、3D 画布、图片、视频和字体。
与其他浏览器呈现引擎比较
Gecko 和 Webkit 还实现了这些博文中所述的大部分架构功能,在某些情况下,甚至在 Chromium 之前就添加了这些功能。
任何浏览器的速度和可靠性都得到提升,这值得庆祝,并且具有实质性的影响。最终目标是改进所有浏览器的基准,以便开发者可以依赖它。
成功金字塔
我的理念是,首先实现可靠性,然后是可伸缩的性能,最后是可扩展性。
与现实世界中的金字塔一样,每一层都为下一层奠定了坚实的基础。
可靠性
如果我们想要实现丰富而复杂的用户体验,那么首先需要一个稳定可靠的平台。核心功能和基础必须正常运行,并长期持续运行。 此外,这些功能也应完美组合,没有奇怪的极端行为或 bug,这一点同样重要。
因此,可靠性是 RenderingNG 最重要的一个部分。 可靠性是良好的测试、质量反馈环、指标和软件设计模式的结果。
为了证明可靠性有多重要,在过去 8 年里,我们大部分时间都只把这部分搞定。首先,我们对系统有深入的了解 - 从错误报告(存在不足之处)进行学习并加以修复,引导全面的测试,并了解网站的性能需求和 Chromium 性能的局限性。然后,我们仔细、循序渐进地设计并推出了关键的设计模式和数据结构。 那时,我们才准备好为响应式设计、可伸缩性和自定义渲染添加真正的下一代基元。
这并不是说,Chromium 在过去一段时间内没有任何改进。 事实上,情况正好相反! 这些年来,随着我们逐步重构和推出每项改进,可靠性和性能稳步持续提升。
测试和指标
在过去 8 年中,我们添加了数万个单元、性能和集成测试。此外,我们还开发了多项全面的指标,用于衡量 Chromium 渲染行为的方方面面:在本地测试、性能基准测试以及在真实网站上使用真实用户和设备时的真实性能。
但是,无论 RenderingNG(或其他浏览器的渲染引擎有多出色)有多出色,如果浏览器之间存在大量 bug 或行为差异,开发 Web 应用依然并不容易。为了解决这一问题,我们还会最大限度地利用 Web 平台测试。这些测试中的每项测试都会验证所有浏览器都应通过的网络平台使用模式。 我们还会密切监控一段时间内通过更多测试以及提高核心兼容性的指标。
Web 平台测试是一项协作式测试。 例如,在针对 CSS 功能进行的 WPT 测试总数中,Chromium 工程师仅添加了大约 10%;其他浏览器供应商、独立贡献者和规范作者贡献了其余的测试。要想壮大可互操作的网络,需要全村之力!
良好的软件设计模式
反过来,如果代码易于理解,并且设计方式能将出错的可能性降到最低,那么可靠地交付优质软件也会更容易。在后续的博文中,我们将对 RenderingNG 的软件设计有更多话说。
可扩缩的性能
RenderingNG 的下一个最重要的方面是实现出色的性能(从速度、内存和能耗等角度来看)。 我们希望用户在与所有网站互动时能够保持顺畅、响应迅速,同时不牺牲设备的稳定性。
但我们不仅需要性能,还需要可扩缩的性能 - 一种在低端和高端机器以及各种操作系统平台上可靠地运行的架构。我称之为纵向扩容(充分利用硬件设备能够实现的所有功能,然后缩减设备大小),以便在需要时最大限度地提高效率并减少对系统的需求。
为此,我们需要最大限度地利用缓存、性能隔离和 GPU 硬件加速。下面我们来分别了解一下。具体而言,我们来看一下每个网页是如何为网页中一项极其重要的互动(滚动)带来效果的。
缓存
在动态的交互式界面平台(例如 Web)中,缓存是显著提升性能的最重要方式。浏览器中最广为人知的缓存是 HTTP 缓存,但渲染也有许多缓存。对于滚动操作而言,最重要的缓存是缓存的 GPU 纹理和显示列表,它们能够实现极快的滚动速度,同时最大限度地减少耗电量并在各种设备上正常运行。
缓存有助于提高滚动的电池续航时间和动画帧速率,但更重要的是,它可以解除与主线程的性能隔离。
性能隔离
在现代桌面设备上,您永远不必担心后台应用会拖慢您当前所用的运行速度。这是因为抢占式多任务处理,而这反过来又是一种性能隔离:确保独立任务不会互相减慢。
在 Web 上,最佳的性能隔离示例是滚动。即使在 JavaScript 速度缓慢的网站上,滚动操作也可以非常流畅,因为它在另一个线程上运行,无需依赖于 JavaScript 和布局线程。我们在 RenderingNG 上投入了大量精力,通过缓存(不仅仅是显示列表,也适用于更复杂的情况),以确保每个可能的滚动都是线程处理的。例如,用于表示位置固定和粘性元素的代码、被动事件监听器以及优质文本渲染。
GPU 加速
GPU 可以显著加快像素生成和绘制到屏幕上的速度。在许多情况下,每个像素都可以与所有其他像素并行绘制,从而大幅提升速度。RenderingNG 的一个关键组件是 GPU 光栅和在任何位置绘制。在所有平台和所有设备上使用 GPU 来超加速 Web 内容的渲染和动画效果。 这在低端设备或非常高端的设备上尤为重要,这些设备通常具有比设备的其他部分更强大的 GPU。
可扩展性:适合相关工作的理想工具
在具备可靠性和可伸缩的性能后,我们便能够在大量工具的基础上进行构建,以帮助开发者扩展 HTML、CSS 和 Canvas 的内置部分,同时不影响任何来之不易的性能和可靠性。
这包括适用于响应式设计、渐进式渲染、流畅性和响应性以及线程式渲染等高级用例的内置及公开 JavaScript API。
以下由 Chromium 倡导的开放 Web API 是由 RenderingNG 实现的,以前被认为不可行。
所有这些功能都是根据开放式规范开发的,并与开放 Web 合作伙伴(其他浏览器的工程师、专家和 Web 开发者)通力协作。在后续的博文中,我们将深入介绍以上各项,并说明 RenderingNG 如何使它们成为可能。
- content-visibility:可让网站轻松避免对屏幕外内容进行渲染工作,而对当前未显示的单页应用视图进行缓存渲染。
- OffscreenCanvas:允许画布渲染(2D canvas API 和 WebGL)在自己的线程上运行,以实现可靠的卓越性能。此项目也是 Web 的另一个重要里程碑,它是首个允许 JavaScript(或 WebAssembly!)从多个线程渲染单个网页文档的 Web API。
- 容器查询:可让单个组件以自适应方式布局,从而取消屏蔽所有即插即用组件(目前为实验性实现)。
- 源隔离:允许网站在 iframe 之间选择启用更多效果隔离。
- 主线程外绘制 Worklet:让开发者能够使用在合成器线程上运行的代码来扩展元素的绘制方式。
除了显式 Web API 之外,RenderingNG 还让我们能够推出几项非常重要的“自动功能”,让所有网站受益:
- 网站隔离:将跨源 iframe 放入不同的 CPU 进程中,以实现更好的安全性和性能隔离。
- Vulkan、D3D12 和 Metal:利用较低级别的 API,这些 API 使用 GPU 的效率高于 OpenGL。
- 更多合成动画:SVG,背景颜色。
我们很期待通过 RenderingNG 解锁的其他即将推出的其他功能包括:
- 滚动链接的动画。
- 隐藏、可搜索和访问的 DOM。
- 共享元素过渡。
- 自定义布局。
- 主线程外合成;分离线程处理和合成。
构成 RenderingNG 的关键项目
下面列出了 RenderingNG 中的主要项目。
CompositeAfterPaint
CompositeAfterPaint 可对样式、布局和绘制进行分离,大幅提高了可靠性和可预测的性能,提高了吞吐量,并在不牺牲性能的情况下使用了更少的内存。
年 | 进度 |
---|---|
2015 | 飞船显示列表。 |
2017 | 发布新的失效操作。 |
2018 | 提交属性树第 1 部分。 |
2019 | 发布属性树第 2 部分。 |
2021 | 项目交付已完成。 |
LayoutNG
完全重写了所有布局算法,大大提高了可靠性和更可预测的性能。
详细了解 LayoutNG。
年 | 进度 |
---|---|
2019 | 发货屏蔽流程。 |
2020 | 发布灵活、编辑。 |
2021 | 邮寄所有其他商品。 |
BlinkNG
我们重构并清理了 Blink 渲染引擎,使其成为完全分离的流水线阶段。这样可以提供更好的缓存、更高的可靠性,以及可重入或延迟渲染的功能,例如内容可见性和容器查询。
无处不在的 GPU 加速
GPU 加速可为大多数内容提供极大的加速,因为每个像素都可以并行处理。它也是提高低端设备(通常仍配备 GPU)上性能的有效方法。
年 | 进度 |
---|---|
2014 | 画布支持。已随 Android 设备上的选择启用内容分发。 |
2016 | 在 Mac 上分发。 |
2017 | 超过 60% 的 Android 网页浏览量使用了 GPU。 |
2018 | 搭载 Windows、ChromeOS 和 Android Go。 |
2019 | 线程式 GPU 光栅化。 |
2020 | 交付剩余的 Android 内容。 |
线程式滚动、动画和解码
需要长期以来将所有滚动、非布局诱导的动画和图像解码从主线程中移除。持续进行中。
年 | 进度 |
---|---|
2011 | 对线程式滚动和动画提供初步支持。 |
2015 | 层合并。 |
2016 | 通用溢出滚动。 |
2017 | 在合成器线程上解码图片。 |
2018 | 合成器线程上的图片动画。 |
2020 | 始终合成固定位置。 |
2021 | 百分比转换动画,SVG 动画。 |
可视化
Chromium 的集中式光栅和绘制进程,可提高吞吐量、优化内存并允许以最佳方式利用硬件功能。它还有其他一些对 Web 开发者来说不太明显但对用户来说非常明显的优势,例如解除对网站隔离的屏蔽,以及将渲染流水线与浏览器界面渲染分离开来。
年 | 进度 |
---|---|
2018 | Android、Mac 和 Windows 上都提供 OOP-R。 |
2019 | OOP-D 已发货。OOP-R 寄送到任何地方(画布照片除外)。SkiaRenderer 适用于 Linux。 |
2020 | SkiaRenderer 适用于 Windows 和 Android。Vulkan 已在 Android 上推出。 |
2021 | SkiaRenderer 适用于 Mac(很快也会在 ChromeOS 上推出)。 |
上表中的术语定义:
- OOP D
- 进程外显示合成器。 屏幕合成与 OS 合成器属于同一种 activity。“进程外”意味着在可视化进程(而不是网页的渲染进程或浏览器界面进程)中执行。
- OOP-R
- 进程外光栅。光栅正在将显示列表转换为像素。“进程外”意味着在可视化进程(而不是网页的渲染进程)中进行。
- SkiaRenderer
- 一种新的屏幕合成器实现,可以支持在一系列不同的底层 GPU API(例如 Vulkan、D3D12 或 Metal)上执行。
线程式和加速画布渲染
这就是 OffscreenCanvas 成为现实的项目。
年 | 进度 |
---|---|
2018 | 寄送 OffscreenCanvas。 |
2019 | 发布 ImageBitmapRenderingContext。 |
2021 | 发布 OOP-R。 |
VideoNG
VideoNG 长期致力于提供高效、可靠且高质量的 Web 视频播放服务。
年 | 进度 |
---|---|
2014 | 引入了基于 Mojo 的渲染框架。 |
2015 | 发布了 Project Butter 和视频叠加层,可使视频渲染更流畅。 |
2016 | 实现了统一的 Android 和桌面设备解码和渲染管道。 |
2017 | 支持 HDR 和色彩校正的视频渲染。 |
2018 | 已交付基于 Mojo 的视频解码流水线。 |
2019 | 已交付基于 Surface 的视频渲染管道。 |
2021 | 在 ChromeOS 上支持 4K 保护的内容呈现。 |
上表中的术语定义:
- 莫约
- Chromium 的下一代 IPC 子系统。
- Surface
- Viz 项目设计中的一个概念。
插图:Una Kravets。