介绍了为什么 Chrome DevTools 在处理生产环境中的性能问题时不足以完全满足需求,以及如何通过生产环境中的性能分析来改进 Web 应用程序的性能。
随着 Web 应用越来越复杂,再加上 JavaScript 是单线程的,Web 应用的扩展性问题变得更加棘手。Chrome DevTools 是我们维持和优化 Web 应用性能的重要工具,但在本地进行性能分析,往往无法真实反映终端用户实际遇到的性能问题。为了更快、更有效地发现并修复性能问题,包括 Facebook、Microsoft、Slack、Dropbox 和 Notion 在内的一些公司已经开始在生产环境中进行性能分析。本文将介绍他们在生产环境中进行性能分析的一些通用方法。
Web 应用难以扩展的一个根本原因,是 JavaScript 的单线程特性。浏览器中的所有工作都必须在 16 毫秒内完成,才能使页面体验达到每秒 60 帧,这意味着你的应用代码要和垃圾回收、浏览器的渲染流程(渲染 / 布局、绘制、合成)争夺这 16 毫秒的时间。一旦超时,浏览器就会掉帧,用户会感受到界面卡顿。
长任务阻塞用户输入的示意图
现在的大型 Web 应用(比如 VSCode、Slack、Notion、Discord、Spotify 等)通常拥有数百万行 JavaScript 代码,这让扩展它们变得更加困难。尽管这些公司都有专门的性能团队,但依然面临维护和优化性能的巨大挑战。而且,单线程性能已经逐渐触顶,难以继续提升。
单线程 JavaScript 核心性能瓶颈图示
随着 Web 应用的规模持续增长,保持其性能变得越来越难,用户也开始明显感觉到应用变慢了。
用户抱怨 Web 应用变慢的截图
Web 开发人员面对性能问题时,能用的工具主要就是 Chrome DevTools,但它在解决终端用户性能问题上确实存在一些局限。
虽然 Chrome DevTools 是性能工程师最常用的工具,但它也有几个关键问题:
终端用户的硬件差异、应用状态不同、操作路径各异,都会导致 Chrome DevTools 无法准确反映实际遇到的性能瓶颈。要准确复现这些问题,通常需要用户提供详细的操作步骤和重现方式,然后开发者还要搭建出相同的运行环境和操作流程。但这种依赖用户主动汇报的方式不稳定,而且大多数性能问题根本不会被用户报告出来。
每次发布新版本时,都可能引入性能回退。在大型项目中,一个版本可能合并了上百个来自不同团队的提交,这使得回退定位变得极其困难。我们见过有些团队会靠猜测回退某些改动来试图恢复性能,但通常没有效果。如果一次回退无效,他们就继续回退其他改动,直到性能指标恢复正常,或者干脆把新指标作为 “新基线” 来接受。
由于缺乏对实际慢路径的可见性,开发者很难发现真正值得优化的地方。
Chrome DevTools 无法真实代表终端用户的代码执行路径,这是根本性的限制。为了克服这些问题,一些公司开始探索在生产环境中进行性能分析的新方法。