[译] 一行 JavaScript 代码居然让 FT.com 网站慢了十倍

性能退化的探索之旅

发现问题

这一切开始于一个警报,首页应用的错误率高于 4% 的阈值。javascript

显示数千个错误页面对咱们的用户产生了切实的影响(还好 CDN 缓存抵消一部分影响)。html

被用户看到的错误页面前端

应用程序的错误日志显示,该应用程序没有任何有关 top stories 的数据。java

诊断问题

首页的工做原理是在一个时间间隔内轮询 GraphQL api 以获取数据,将该数据存储在内存中并根据请求渲染它。从理论上讲,若是请求失败,应该保留以前稳定的数据。进一步深刻日志,咱们看到对 GraphQL api 的请求失败了,可是是有错误而不是超时——或者至少是不一样类型的超时。node

FetchError: response timeout at https://….&source=next-front-page over limit: 5000
复制代码

奇怪的是,API 的响应时间彷佛远低于首页设置的 5 秒超时。这让咱们相信问题出如今首页和应用程序之间的链接上。咱们作了些尝试——在二者之间使用 keepAlive 链接,分散请求,这样它们就不会同时发起。这些彷佛都没有产生任何影响。android

更神秘的是 Heroku 上显示的响应时间。第 95 百分位数约为 2-3 秒,而最大值有时达到 10-15 秒。因为首页被 Fastly 高度缓存,包括 stale-while-revalidate 头,许多用户可能不会注意到。但这很奇怪,由于首页真的不该该作不少工做来渲染页面。全部数据都保存在内存中。ios

首页的 Heroku 响应时间git

所以咱们决定对本地运行的应用程序副本进行一些分析。咱们将经过使用 Apache Bench 每秒发出10个请求,共发出 1000 个请求来复制一些负载。github

ab -n 1000 -c 10 http://local.ft.com:3002/
复制代码

使用 node-clinicnsolid,咱们能够对内存、CPU 和应用程序代码有更深的理解。运行它们,确认咱们能够在本地复现该问题。首页须要 200-300 s 才能完成测试,超过 800 个请求不成功。相比之下,在文章页面上运行相同的测试须要大约 50 秒。后端

测试用时:305.629 秒
完成的请求:1000
失败的请求:876
复制代码

并且你看,n-solid 的图表显示事件循环的滞后超过 100 毫秒。

在作加载测试时事件循环滞后

使用 n-solid 的 CPU 分析器,咱们能够精肯定位阻塞事件循环的确切代码行。

火焰图显示致使滞后的函数

修复问题

罪魁祸首是...

return JSON.parse(JSON.stringify(this._data));
复制代码

对于每一个请求,咱们使用 JSON.parse/stringify 来建立数据的深克隆。这种方法自己不坏 —— 多是深克隆比较快方法之一。但它们是同步方法,所以在执行时会阻塞事件循环。

在咱们的案例中,这个方法在每一个页面渲染(对于每一个被渲染的部分)中屡次调用,具备大量数据(每次执行时整个页面所需的数据),而且咱们有几个并发请求。因为 Javascript 是单线程的,所以这将对应用程序尝试执行的全部其余操做产生连锁反应。

深克隆数据的缘由是,咱们会根据请求中的一些信息(例如,是否启用了特定功能的切换),来改变对象。

为了解决这个问题——并减轻克隆全部内容的须要——咱们在检索时对对象应用了深度冻结,而后在数据被改动的地方克隆特定位。这仍然执行同步克隆——但仅限于更小的数据子集。

结论

修复好后,咱们从新运行了负载测试,并在很短的时间内完成,0 次错误。

测试用时:37.476 秒
完成的请求:1000
失败的请求:0
复制代码

咱们发布了修复程序,看到响应时间和错误(🤞🏼)当即减小,并但愿一些用户开心!

修复后首页的响应时间

关于将来

  • 对其余一些应用程序运行此分析,并了解咱们能够进一步优化和/或减小 dyno 大小,这也会颇有趣。
  • 咱们可让事件循环更可见吗?
  • 咱们的首页应该是 stale-on-error——因此为何仍然会看到数以千计的错误页面?这个数字好仍是坏?

感谢 Samuel Parkinson 的付出。

若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索