一行 JS 代码竟然让 FT.com 网站慢了十倍

一行 JS 代码竟然让 FT.com 网站慢了十倍
最新回答
我污但不色

2022-06-27 03:19:39

一行JS代码导致FT.com网站性能下降十倍的原因在于使用了同步的深克隆方法JSON.parse(JSON.stringify()),该方法在数据量大且并发请求多的情况下阻塞了事件循环。

  • 问题发现:FT.com首页应用的错误率超过阈值,用户看到错误页面,日志显示应用程序缺少top stories数据。
  • 问题诊断

    首页轮询GraphQL API获取数据并存储在内存中,请求失败时应保留之前的数据。

    日志显示API请求失败,但响应时间远低于设置的5秒超时,怀疑问题出在首页与应用程序的连接上。

    尝试使用keepAlive连接和分散请求,但未解决问题。

    Heroku显示的响应时间异常,第95百分位数约为2-3秒,最大值有时达到10-15秒。

  • 深入分析

    本地运行应用程序副本进行负载测试,使用Apache Bench每秒发出10个请求,共1000个请求。

    使用node-clinic和nsolid分析内存、CPU和应用程序代码,发现事件循环滞后超过100毫秒。

    通过n-solid的CPU分析器,精确定位到阻塞事件循环的代码行:return JSON.parse(JSON.stringify(this._data));。

  • 问题原因

    每个请求使用JSON.parse/stringify进行深克隆,该方法本身不坏,但它是同步的,执行时会阻塞事件循环。

    在FT.com的案例中,该方法在每个页面渲染中多次调用,处理大量数据,并且有多个并发请求,导致应用程序性能显著下降。

  • 解决方案

    在检索数据时应用深度冻结,然后在数据被改动的地方克隆特定位,减少同步克隆的数据量。

    修复后重新运行负载测试,响应时间显著缩短,错误次数降为0。

  • 结论

    修复后,首页的响应时间恢复正常,错误率立即下降。

    未来计划包括对其他应用程序进行类似分析,优化性能,并提高事件循环的可见性。