在 Discourse 核心、插件或主题中进行客户端开发时,务必考虑其对性能的影响。Google 的 “Tachometer” 项目提供了一个统计上严谨的基准测试工具,我们可以利用它来准确衡量更改带来的影响。
本质上,该工具会接收一个 URL 列表,并以“轮询”(round-robin)方式加载它们。每次页面加载时,它会采集一些性能指标。经过数百或数千次迭代后,它会生成一个对比表格。
这种“轮询”方法的美妙之处在于,它有助于减少外部因素对测量结果的影响。
步骤 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,主要有两种方法:
如果你的更改足够小,可以轻松通过功能标志(feature-flag)控制,那么你可以添加逻辑,根据 URL 查询参数 来切换它。然后你的两个 URL 可以是:
http://localhost:3000?flag=before
http://localhost:3000?flag=after
如果更改太大而无法这样做,你可以创建一个 git worktree,并在另一个端口上从该 worktree 启动 第二个 Rails 副本:
git worktree add ../discourse-after my-branch
cd ../discourse-after
bundle install
pnpm install
EMBER_ENV=production UNICORN_PORT=3001 bin/dev
两个副本共享相同的数据库和 Redis,因此请确保两个分支之间没有对方缺失的迁移文件。
然后你的两个 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:运行基准测试
为了减少噪声,请停止工作站上任何无关的活动,然后使用类似以下命令启动基准测试:
pnpx tachometer --config ./bench.json
完成后,你应该能看到更改前后的性能对比。
注意事项
与任何此类实验一样,值得考虑其局限性。例如:
-
开发工作站上的性能差异可能无法直接映射到其他浏览器/设备上
-
Discourse 在开发模式下的启动过程与在生产模式下并不完全相同。在进行结构性更改(例如框架更新)时,这一点可能很重要
-
性能通常会根据应用程序状态(例如正在渲染的主题数量)而变化,因此你的结果可能无法在其他环境中完全复现
本文档受版本控制 - 建议修改请 在 github 上提交。
