使用 Google 的“速度计”测量 Discourse 中的 JS 性能变化

在处理 Discourse 核心/插件/主题中的客户端工作时,考虑性能影响至关重要。Google 的“Tachometer”项目提供了一个统计上严谨的基准测试工具,我们可以用它来明确衡量变更带来的影响。

本质上,该工具会获取一组 URL 列表,并以“轮询”方式加载它们。对于每次页面加载,它会进行一些性能测量。经过数百/数千次迭代后,它会生成一个对比表格。

这种“轮询”方法的好处在于,它有助于减少外部因素对测量结果的影响。

步骤 1:添加 performance.measure()

具体方法会根据您的测试内容而有所不同。但根本上:您需要引入一个 performance.measure() 值供 Tachometer 读取。

如果您想测量 Discourse 启动和渲染所需的时间,可以使用内置的“discourse-init-to-paint”测量项。对于其他情况,您可以引入自己的 performance.measure 并使用它。

您可以使用浏览器开发者工具中的“性能”选项卡检查其是否正常工作:

如果您试图测量需要用户交互的活动(例如打开菜单),可以通过在初始化器中添加类似以下内容来实现,即在页面加载 1 秒后点击按钮:

setTimeout(() => document.querySelector(".my-button").click(), 1000);

步骤 2:确定测试 URL

首先,请确保您正在以生产模式构建 Ember 资源。这可以通过使用 EMBER_ENV=production 启动服务器来实现。

要获取两个不同的 URL,主要有两种方法:

如果您的变更足够小,可以轻松通过功能标志控制,那么您可以添加逻辑,使其基于 URL 查询参数 进行切换。这样,您的两个 URL 可以是:

http://localhost:3000?flag=before
http://localhost:3000?flag=after

如果变更太大而不适用上述方法,您可以将 Discourse 克隆到第二个目录,并启动 第二个 Rails 副本

EMBER_ENV=production UNICORN_PORT=3001 bin/dev

然后您的两个 URL 将是:

http://localhost:3000
http://localhost:3001

如果采用此方法,请确保这两个应用副本都包含您在本文步骤 1 中引入的性能遥测数据。

步骤 3:配置 Tachometer

这是我的 bench.json 文件,它将对每个目标采集 300 个样本:

{
  "timeout": 5,
  "sampleSize": 300,
  "benchmarks": [
    {
      "measurement": {
        "mode": "performance",
        "entryName": "discourse-init-to-paint"
      },
      "expand": [
        {
          "url": "http://localhost:3000",
          "name": "before"
        },
        {
          "url": "http://localhost:3001",
          "name": "after"
        }
      ]
    }
  ]
}

步骤 4:运行基准测试

为了减少干扰,请停止工作站上的任何无关活动,然后使用类似以下命令启动基准测试:

npx tachometer@latest --config ./bench.json

完成后,您应该会看到“之前/之后”的性能对比。

注意事项

与任何此类实验一样,值得考虑其局限性。例如:

  • 您的开发工作站上的性能差异可能无法直接映射到其他浏览器或设备上

  • Discourse 通过 Ember-CLI 代理的启动过程与生产环境并不完全相同。在进行结构性变更(例如框架更新)时,这一点可能很重要

  • 性能通常会根据应用程序状态(例如正在渲染的主题数量)而变化,因此您的结果可能无法在其他环境中完全复现


本文档已进行版本控制——建议在 GitHub 上提出修改建议。

17 个赞