性能是编辑器应用程序的一项关键特性,区块编辑器也不例外。

指标

为了确保区块编辑器在各个版本发布和开发过程中始终保持高性能,我们使用性能基准测试任务来监控一些关键指标。

一些主要的重要指标包括:

  • 加载时间:加载编辑器页面所需的时间。这包括服务器响应时间、首次绘制时间、首次内容绘制时间、DOM 内容加载完成时间、加载完成时间以及首个区块渲染时间(文章和站点均是如此)。
  • 输入时间:在编辑器中输入时浏览器作出响应所需的时间。
  • 区块选择时间:用户选择区块后浏览器作出响应所需的时间。(插入区块也等同于选择区块。监控选择操作即可覆盖这两个指标)。

关键性能决策与解决方案

Data 模块异步模式

WordPress 包和区块编辑器的 Data 模块基于 Redux。这意味着状态是全局保存的,每当发生变化时,依赖该状态的组件(UI)都可能会更新。

随着渲染组件数量的增长(例如在长文章中),性能会受到影响,因为全局状态充当着面向所有组件的事件分发器。这是 Redux 应用程序中的一个常见陷阱,而 Gutenberg 使用 Data 模块的异步模式解决了这个问题。

异步模式的理念是:你可以决定以同步还是异步的方式刷新/重新渲染 React 组件树的某一部分。

在这种情境下,异步渲染意味着:如果全局状态中触发了更改,订阅者(组件)不会被同步调用,而是等待浏览器空闲时再对 React 树执行更新。

基于在编辑某个区块时,对该区块的更新很少会影响内容的其他部分这一理念,区块编辑器画布仅以同步模式渲染选中的区块,其余所有区块均以异步方式渲染。这确保了编辑器在文章不断增长时依然保持响应。

性能基准测试任务

我们提供了一个用于比较多个分支/标签/提交之间性能的工具。你可以在本地按如下方式运行:npm exec --no release-cli -- perf [branches],例如:

npm exec --no release-cli -- perf trunk v8.1.0 v8.0.0

在拉取请求中,基准分支列(例如 trunk)是在拉取请求所基于的提交上进行测量的,而不是在该分支的当前最新位置上测量,因此这两列都与合并提交的构建来源相匹配。

传入 --suites 以及以逗号分隔的 spec 名称列表(test/performance/specs/*.spec.js,不含扩展名),即可运行套件的一个子集。CI 工作流利用它将套件拆分为并行运行的多个分片(shard),每个分片在同一运行器上测量所有分支。它还会在一个单独的任务中一次性构建插件,并通过 --plugins-dir <dir> 将插件传递给每个分片(每个分支的预构建插件位于 <dir>/<sanitized branch name>),这使该命令使用当前检出的代码作为测试运行器,而不是进行克隆和构建。

为了获得最准确的结果,在运行测试时使用完全相同的测试版本和环境(主题等)非常重要,各分支之间唯一需要不同的是 Gutenberg 插件的版本(或用于构建插件的分支)。

为实现这一点,该命令首先会准备以下文件夹结构:

│
├── test/performance/specs/*
|   实际要运行的性能测试
│
├── test/emptytheme
|   测试环境所使用的主题。(站点编辑器)
│
│── envs/branch1/.wp-env.json
│   branch1 的 wp-env 配置文件(与其他所有分支类似,只是插件文件夹不同)。
│── envs/branch1/plugin
│   为 branch1 构建的 Gutenberg 插件克隆(git checkout branch1)
│
└── envs/branchX
    所有其他分支都会复制 perf-envs/branch1 的结构。

一旦上述目录准备就绪,性能命令会循环遍历各个性能测试套件(文章编辑器和站点编辑器),并执行以下操作:

  1. 启动 branch1 的环境
  2. 运行当前套件的性能测试
  3. 停止 branch1 的环境
  4. 对所有其他分支重复前 3 个步骤
  5. 计算当前套件所有性能指标的中位数。

所有测试套件执行完毕后,将打印一份摘要报告。

使用 CodeVitals 跟踪性能。

每个提交的性能结果都会被推送到 codevitals,并可在那里的 Gutenberg 仪表板上查看。这些图表使我们能够跟踪给定指标随时间的演变。

因此,确保所计算的指标保持稳定非常重要。也就是说,如果在相同的代码和环境下两次运行相同的测试,得到的结果应当是相近的。

我们的性能任务运行在 GitHub CI 上,这意味着我们无法信任两次类似任务运行之间所得数字的一致性。例如,GitHub CI 可能会随时间为我们分配不同的 CPU 和内存资源。为了缓解这个问题,每次在 trunk 分支上运行性能任务时,我们都会将当前提交的性能与固定的参考提交哈希值进行比较,这使我们无论环境如何变化,都能一致地跟踪当前提交与参考提交之间的相对差异。

更新参考提交

Gutenberg 仅支持两个 WP 版本,这会在两个方面影响性能任务:

  • 当 Gutenberg 支持的最低版本发生变化时,用于运行性能任务的基础 WP 版本也需要更新。为此,我们依赖插件 readme.txt 文件中的 Tested up to 标志。因此,每当该标志发生变化时,用于性能任务的版本也会随之改变。
  • 更新用于性能任务的 WP 版本意味着,用于性能测试稳定性的参考提交很有可能会与所使用的 WP 版本变得不兼容。因此,每当 readme.txt 中的 Tested up to 标志被更新时,我们还必须更新 tools/release/resolve-performance-branches.mjs 中所使用的参考提交。

新选择的参考提交哈希值需要满足以下要求:

  • 与 “Tested up to” 标志中使用的新 WP 版本兼容。
  • 已在 “codevitals.run” 上针对所有现有指标进行了跟踪。

更新 wordpress-develop

当发布更改了 WordPress 最低要求版本的插件更新时,需要为任何失去支持的分支更新 Core SVN 中的端到端测试 GitHub Actions 工作流。否则,发布后该工作流在该分支上的首次运行将会失败。

可以通过向测试矩阵添加 gutenberg-version 输入来在工作流中固定插件版本。Core-59221 是针对 6.4 分支进行此类更改的一个示例。

注意:请始终使用包含错误修复的最终版本(即 x.y.2 或 x.y.3)。如果最终版本尚未确定,请创建一个 Trac 工单,以免被遗忘。

选择提交的一种简单方法是,选取 trunk 上性能任务通过的最新提交。

进一步了解