几个月前,我写过一篇关于使用 WebPageTest的文章,更具体地说是它的 RESTful API,来监控网站的性能。毫无疑问,它提供的数据可以转化为宝贵的信息,供工程师调整系统的各个部分,使其性能更佳。
但这个工具究竟如何融入您的开发工作流程?您应该何时运行测试,以及对结果进行哪些操作?如何将其可视化?
现在我们能够通过 RESTful API 以编程方式获取性能指标,因此我们应该考虑如何持久化这些数据并跟踪其随时间推移的变化。这意味着能够查看特定页面的加载时间如何受到新功能、资源或基础设施更改的影响。
我着手创建一个工具,让我能够编译和可视化所有这些信息,并且我希望以一种允许其他人也使用它的方式来构建它。

愿望清单
我希望这个工具能够
- 手动运行测试或由第三方触发测试,例如 GitHub 发布提交后触发的 Webhook
- 以可配置的时间间隔运行定期测试
- 测试多个 URL,并能够配置不同的测试位置、设备和连接类型
- 对任意数量的性能指标进行分组并在图表上显示它们
- 为任何性能指标定义预算并在图表上与结果一起可视化它们
- 配置警报(电子邮件和 Slack),以便在指标超出预算时发送
在继续之前,我必须指出,市场上有一些成熟的解决方案可以提供上述所有功能。像 SpeedCurve 或 Calibre 这样的公司提供专业的监控工具作为服务,如果您正在经营企业,则应该认真考虑使用它们。它们使用 WebPageTest 的私有实例,而不是公共实例,这意味着没有使用限制,也没有不可预测的可用性。
我创建的工具,以及我将在本文中向您介绍的工具,是这些服务的简易免费替代方案。我之所以构建它,是因为我的预算不允许我每月支付性能监控服务的费用,我相信其他个人、非营利组织和开源项目也面临着同样的问题。我的目标是将这种类型的工具带给那些可能无法获得它的人。
想法
我心中所想的系统必须具备三个关键组件
- 一个应用程序,用于侦听测试请求并与 WebPageTest API 通信
- 一个数据存储,用于持久化测试结果
- 一个可视化层,用于显示它们,并使用一系列图表来显示各种指标随时间推移的变化
我真的很想构建一些东西,让各个水平的专家都能免费设置和使用,这极大地影响了我对平台架构和基础设施的决策。
这看起来可能是一种不寻常的方法,但 GitHub 实际上是实现 #2 和 #3 的一个非常有趣的选择。使用 GitHub 的 API,您可以轻松地从存储库读取和写入文件,因此您可以有效地将其用作持久性数据存储。最重要的是,GitHub Pages 使同一个存储库成为提供网站的绝佳位置。您将获得快速安全的托管服务,并可以选择使用自定义域名。如果您愿意使用公共存储库,所有这些都是免费的。
至于 #1,我构建了一个小型 Node.js 应用程序,它接收测试请求,将它们发送到 WebPageTest,检索结果并将它们作为数据文件推送到 GitHub 存储库,然后可视化层将提取这些文件。我之前在构建 Staticman 时使用过这种方法,效果非常好。
下图显示了该想法的要点。

哦,在某个时刻我需要一个名字。我把它命名为 SpeedTracker。
您可以 在这里查看其运行情况,或者通过 此链接直接开始使用它。如果您想了解更多关于它在幕后如何工作、构建它的过程以及我预期的发展方向,请继续阅读。
构建仪表盘
我非常喜欢 Jekyll。对于那些不熟悉它的人来说,Jekyll 是一个程序,它从各种格式(Markdown、JSON、YAML 甚至 CSV)的文件中获取结构化内容并生成 HTML 页面。它是更广泛的 静态网站生成器家族的一部分。
它与本项目特别相关,因为它与 GitHub Pages 具有原生集成,这使得任何存储库都可以在每次收到新内容或更新内容时自动构建 Jekyll 网站,并在指定的 URL 上即时提供生成的 HTML 文件。考虑到这一点,我可以让 API 层将测试结果写入 JSON 文件,并让 Jekyll 读取并将它们输出到网页。
通过将数据存储在 GitHub 存储库中,我们让用户可以控制自己的数据。它不会隐藏在某些服务的数据库中的某个地方,它位于一个免费的开放存储库中,可以轻松地下载为 ZIP 文件。并且通过使用 JSON,我们选择了数据通用的格式,使其更容易在其他地方重复使用。
为了满足能够使用不同的设备、连接类型和位置测试多个站点的需求,我引入了配置文件的概念。每个测试都必须针对一个配置文件运行,该配置文件包含一个文件(参见示例),其中包含有关要测试的 URL 以及要传递给 WebPageTest 的任何参数的信息。
在此文件中,您还可以定义一个以小时为单位的间隔,在该间隔内将重复对给定配置文件进行测试。您可以通过更改配置文件中的 interval
属性来更改此值或完全删除计划的测试。
现在的挑战是如何从由一堆 JSON 文件支持的静态站点提供多个配置文件的结果并提供一些基本日期过滤功能(例如能够深入了解过去一周、一个月或一年的结果)。我不能简单地让 Jekyll 将整个数据集转储到一个页面上,否则生成的 HTML 文件将很快变得过大。
Jekyll 遇见 React
我首先在一个文件夹和文件结构中组织文件,以便按日期和配置文件对测试结果进行分组。Jekyll 可以遍历此结构并生成每个站点所有可用数据文件的列表,以及它们的完整路径。
有了此列表,我就可以构建一个客户端应用程序,该应用程序在给定配置文件和日期范围的情况下,可以异步获取显示受影响结果所需的文件,提取和编译各种指标,并将它们绘制在一系列交互式图表上。
我使用 React 构建了它。

性能预算
让团队树立正确的网络性能意识的一个好方法是为一个或多个指标定义预算并严格遵守它们。Tim Kadlec 在 这篇文章中对它进行了比我更好的解释,但基本思想是您指定您的网站必须在特定类型的连接上在一定时间内加载。
每次计划向站点添加新功能或资源时,都必须考虑该阈值。如果新添加的内容使您超出预算,则必须放弃它,或者找到一种方法来删除或优化现有功能或资源,以便为新的功能或资源腾出空间。
我希望在平台中为预算提供一个显着的位置。在创建配置文件时,您可以为捕获的任何指标设置预算,并且一条水平线将与数据一起显示在相应的图表中,为您提供有关站点运行情况的直观指示。

还可以定义在超出任何预算时触发的警报,以便您和您的团队可以在事情看起来不太好的时候通过电子邮件或 Slack 立即收到通知。
集中式服务
这个项目的核心思想是让这种类型的工具免费且对每个人都可用。将其开源显然是第一步,并且您可以使用免费服务来部署前端(GitHub Pages 或 Netlify)和后端(Heroku 或 now)这一事实绝对有所帮助。但即便如此,我仍然觉得必须安装和部署 API 层会为经验不足的人带来障碍。
因此,我以这样一种方式构建了应用程序,即单个实例可以用于将测试结果传递到多个站点和 GitHub 存储库,因此它实际上可以作为一个许多人可以使用集中式服务。有一个服务器运行着 API 的公共实例,任何人都可以免费使用。
这意味着您入门所需的只是在 GitHub 存储库中安装 Jekyll 站点,添加用户名 speedtracker-bot 作为协作者,配置配置文件和其他一些内容,然后您就可以开始了。
下面的屏幕截图可以指导您完成此过程。
接下来做什么
如果此工具成功帮助你们中的一些人提高网站的性能,我将非常高兴。如果您使用它并决定捐出一些时间来帮助使其对每个人都更好,我将更加高兴!
我可以立即想到一些我想看到的事情
- 添加对图表上的注释的支持,以标记特定事件,例如基础设施更改或重要功能发布
- 已经可以有一个 GitHub Webhook 触发新的测试,但我们可以更进一步,实际上读取 Webhook 有效负载的内容以在图表上创建注释以标记提交或发布
- 更轻松地显示自定义指标
- 添加对脚本编写的支持
- 更好的文档和测试
如果您觉得自己可以提供帮助,请务必参与进来。如果您在入门时有任何疑问或问题,请发送推文给我。
测试愉快!
这看起来很棒!您是否有关于您希望获得帮助的更具体的愿景?似乎是一件很酷的事情,我很想看看我是否可以贡献任何东西。
巧合的是,我一直在寻找类似的东西(但简单得多),用作 GitHub README 上的徽章,这是我周末制作的—— 这是 CSS-Tricks
嗯,失败了,无法嵌入图像 ¯\_(ツ)_/¯
谢谢!我认为,目前,获得一些来自设置和使用该平台的人员的反馈将非常棒,以便我们能够报告和修复问题,并开始收集对未来版本的特性请求。
恭喜,Eduardo。伟大的成就。我最近也遇到了类似的问题。由于我不太了解后端编程,所以我尝试将手动测试的结果馈送到Splunk。长话短说,我没有获得我真正想要的东西,但我认为这主要是因为我对 Splunk 以及如何处理数据以获得所需的可视化模型缺乏经验。
由于我对这个主题本身很感兴趣,我想参与并帮助这个项目。请告诉我您希望如何进行。
谢谢!很高兴你喜欢它。
正如我之前对 Alex 提到的,在这一点上,获得一些来自设置和使用该平台的人员的反馈将非常棒,目标是报告和修复任何现有问题,然后开始收集对未来版本的特性请求。
非常棒的东西,迫不及待地想明天就开始创建几个这样的东西。
这似乎比设置 SiteSpeed.io 的门槛低得多,而且比使用 Speedcurve 便宜得多(即免费)。
我在即将进行的演讲中谈到了性能和监控,因此能够分享一些示例将非常棒,完美的时机,谢谢!
听起来很棒!
请告诉我你的进展情况,如果你发布了你的演讲,请分享链接。 :)
我一直在寻找类似的工具。这太棒了。你赢得了我的尊重,伙计!谢谢
看起来确实很酷。但是,当我发布到 API 时,我收到一个通用的“INVALID_CONFIGURATION”错误。我不确定它指的是哪个配置,但即使使用示例 YML 和 JSON 文件,仍然会给我这个错误。
抱歉。你能将 GitHub 用户名和存储库发送到 mail at eduardoboucas dot com 吗?我会查明发生了什么事。
这很棒,谢谢!