查找并修复 VS Code 扩展程序的性能问题
本文最初发表于我的个人博客,
现转载至此,供开发者社区参考。
我正在开发一款名为Abracadabra 的VS Code 扩展,它能为 JavaScript 和 TypeScript 提供直观的自动重构功能。
最近,我一直在寻找性能瓶颈以提升速度。在本文中,我将解释我是如何做到这一点的,以便您也可以这样做。
如何判断自己需要提升表现?
我创作时,总是尽量遵循这个原则:
“让它成功,让它正确,让它快速。”
——肯特·贝克
Abracadabra 是我的一个业余项目。我最初开发了所需的功能并发布了。随着开发过程的推进,我不断重构代码以提高可读性和可维护性。在这个过程中,我做出了一些从性能角度来看略显天真的决定,但它们极大地简化了开发工作。在第一个版本发布几个月后,我已经开发了 20 多个自动化重构。如今,这些重构极大地提高了我的编码效率。
大多数重构操作都以 VS Code快速修复的形式呈现。VS Code 会根据光标所在位置,通过灯泡图标💡告诉你相关的重构操作。
为了确定哪些重构是相关的,Abracadabra 会尝试逐一执行。任何可能改变代码的重构都会被视为相关的。每当光标位置发生变化时,VS Code 都会向 Abracadabra 提出相同的问题:当前选区内哪些代码需要进行相关的重构?因此,每次光标位置发生变化时,Abracadabra 都会重新计算目录中的所有重构。
听起来性能不太好,对吧?
事实上,在第一个版本发布两周后,我就考虑过这个问题。然而,当时并不需要。尽管理论上存在问题,但我并没有感受到实际使用中的性能问题。因此,这种简单的实现方式就足够了。它保持了代码的简洁,让我能够专注于开发,并更好地理解问题。
提高性能意味着编写不那么简单、更难维护的代码,以使其速度足够快,满足用户需求。
提高性能会牺牲代码的可维护性。
所以我认为,在不衡量绩效的情况下就不应该提升绩效。要衡量绩效。这样你才能知道是否需要改进,或者绩效是否已经足够好。
如何衡量 VS Code 扩展的性能?
VS Code 提供了相当不错的工具来实现这一点。
显示正在运行的扩展程序
首先,你需要调试你的扩展程序。你肯定希望在修改前后分别测试其性能。调试扩展程序会打开一个扩展程序主机,它会编译你的扩展程序代码,这样你就可以实际运行它了。
在扩展主机中,打开调色板(⌘ ⇧ P/ Ctrl Shift P),然后搜索“显示正在运行的扩展”。
这将打开一个标签页,其中列出了您正在运行的扩展程序:
从这个标签页首先可以看到的是启动激活时间。它显示了每个分机激活所需的时间。
一般来说,如果你的扩展程序激活时间超过 500 毫秒,那么你可能可以采取一些措施来加快激活速度——如果你还没有这样做,那么将你的扩展程序打包是一个好主意。
如果你低于这个数值,我觉得没问题。100-200毫秒左右就很好了。低于这个数值就更棒了😉👍
以上指的是启动激活时间。但您可能更关心扩展程序的运行时性能。那么我们该如何跟踪它呢?
记录扩展配置文件
在右上角,您会看到一系列图标,这些图标可让您在运行时记录扩展程序的性能概况。
点击录制按钮(圆圈中的点)。它会变成红色,表示正在录制。
然后,回到你的代码。触发你的扩展程序。以 Abracadabra 为例,我怀疑快速修复功能存在性能问题,所以我移动光标在代码中,触发了快速修复。
完成后,返回“运行扩展”选项卡并停止录制。然后,点击最左侧的图标下载.cpuprofile刚刚录制的内容。
此 CPU 配置可在某些开发者工具中加载。您可以使用 VS Code 中提供的开发者工具!再次打开调色板,然后搜索“切换开发者工具”。
如果您熟悉 Chrome 开发者工具,那么操作方法也一样。打开JavaScript 分析器标签页。这个标签页是隐藏的:您需要点击三个点菜单 → 更多工具 → JavaScript 分析器。
接下来,你可以开始分析 JS 代码——但我们已经使用 VS Code 运行扩展完成了这项工作。你还可以使用“加载”按钮来加载你的代码.cpuprofile。
注意:在 macOS 系统中,如果 Finder 没有显示所有文件扩展名,它可能会将文件保存为 `.php` 格式,.cpuprofile.txt而您不会注意到。如果您无法在开发者工具中发现这一点,请使用终端将其重命名为正确的扩展名(删除 `.php`.txt部分)。
分析个人资料
我更喜欢使用火焰图,它更直观。
我假设你知道如何解读火焰图。
从这个具体案例中,我们可以看出两点:
- 代码会反复扩展
parse(),最终会耗费大量时间。 - 每次重构都会运行一次
provideCodeActions(),这也有可能得到优化。
如果放大一点,就更清楚了:
所以我回到代码中,针对这一点进行了优化。
我只解析了一次代码,然后将抽象语法树(AST)提供给所有重构。之后,我收集了所有可用的重构列表,并只将其提供给 VS Code 一次。以下是修改后的性能分析结果:
好多了。😘👌
轶事:追求性能优化会使代码变得不那么直观。
正如你所见,对 Abracadabra 进行性能分析后,我确信问题本质上是由于每次重构都对同一段代码进行了重复解析。这种想法过于简单,所以我进行了优化,现在代码只被解析一次。
但是,当我这样做的时候,却制造出了之前并不存在的问题!我不得不去解决这些问题。
实际上,所有重构操作现在都共享对同一个抽象语法树(AST)的引用。如果其中一个重构操作修改了这个引用,就会给其他重构操作带来问题。克隆AST听起来像是一个解决方案。我尝试过这种方法,并在之后测试了性能。结果更糟。事实上,每次重构操作之间克隆AST的开销比每次都解析代码还要大。
这就是性能优化的核心:不要猜测,要测量。有时候你会猜对,有时候则不会。
实际的解决方法是确保每次重构在运行快速修复时都不会改变抽象语法树(AST)。为了优化代码,我不得不增加一些复杂性。这通常是性能优化过程中不可避免的情况。这也是我遵循 Kent Beck 的理念的原因:如果代码足够简单,就可以轻松地在必要时进行性能调整。
哦,还有一个实用的小技巧:当你这样做的时候,最好留下一条注释,解释一下为什么这部分代码不能简化。你未来的自己和同事都会感谢你的。
结论
如果您正在开发 VS Code 扩展,我希望本指南能够帮助您找到并修复性能问题。
如果你在使用 VS Code 时遇到性能问题,我建议你阅读他们的 wiki 页面,了解性能问题。
如果你使用 VS Code 编写 JavaScript 或 TypeScript 代码,我强烈推荐你试试Abracadabra。我精心打造的这些自动化重构工具既实用又快捷,应该能每天为你节省大量时间。对我来说确实如此 🙂
最后,我希望我之前能让你重新思考如何处理性能问题。确保它能正常运行,确保它运行正确,确保它运行速度快。你觉得呢?
文章来源:https://dev.to/nicoespeon/find-and-fix-performance-issues-of-your-vs-code-extension-133p








