jjzjj

Vite 4.3 正式发布,速度全面提升!

CUGGZ 2023-09-23 原文

4 月 20 日,Vite 4.3 正式发布。在这个版本中,Vite 团队专注于改进  devServer 的性能。简化了解析逻辑,优化了热路径,并对查找 package.json、TS 配置文件和一般解析 URL 实现了更智能的缓存。与 Vite 4.2 相比,这个版本的速度得到了全面提升!

性能提升

以下是性能改进的具体数据,由 sapphi-red/performance-compare 测试得出,该测试会以 1000 个 React 组件测试应用的冷启动和热启动时间以及根节点和叶节点组件的 HMR 时间:

Vite (babel)

Vite 4.2

Vite 4.3

改进

开发冷启动

17249.0ms

5132.4ms

-70.2%

开发热启动

6027.8ms

4536.1ms

-24.7%

根 HMR

46.8ms

26.7ms

-42.9%

叶 HMR

27.0ms

12.9ms

-52.2%

Vite (swc)

Vite 4.2

Vite 4.3

改进

开发冷启动

13552.5ms

3201.0ms

-76.4%

开发热启动

4625.5ms

2834.4ms

-38.7%

根 HMR

30.5ms

24.0ms

-21.3%

叶 HMR

16.9ms

10.0ms

-40.8%

此性能运行的规格和版本:

  • CPU:Ryzen 9 5900X,内存:DDR4-3600 32GB,SSD:WD Blue SN550 NVME SSD
  • Windows 10 专业版 21H2 19044.2846
  • Node.js 18.16.0
  • Vite 和 React 插件版本
  • Vite 4.2 (babel): Vite 4.2.1 + plugin-react 3.1.0
  • Vite 4.3 (babel): Vite 4.3.0 + plugin-react 4.0.0-beta.1
  • Vite 4.2 (swc): Vite 4.2.1 + plugin-react-swc 3.2.0
  • Vite 4.3 (swc): Vite 4.3.0 + plugin-react-swc 3.3.0

Vite 团队将继续致力于提升 Vite 的性能,正在为 Vite 开发一个官方基准测试工具,以获得每个 Pull Request 的性能指标。vite-plugin-inspect 现在有更多与性能相关的功能,可以帮助开发者确定哪些插件或中间件是应用性能的瓶颈。页面加载后使用 vite --profile(然后按 p)将保存 devServer 启动的 CPU 配置文件。可以在应用中将它们作为 speedscope 打开以识别性能问题。

接下来,Vite 团队决定今年做一个 Vite 主版本,以配合 9 月 Node.js 16 的 EOL,放弃对 Node.js 14 和 16 的支持。

为什么 Vite 4.3 这么快?

更智能的解析策略

Vite会将所有接收到的URL和路径解析为目标模块。在 Vite 4.2 中,存在很多冗余的解析逻辑和不必要的模块搜索。为了减少计算和文件系统调用,Vite 4.3 使解析逻辑更简单、更严格和更准确。

更简单的解析

Vite 4.2严重依赖 resolve 包来解析依赖的 package.json,查看 resolve 的源码发现解析 package.json 时有很多无用的逻辑。Vite 4.3 摒弃了 resolve,遵循更简单的 resolve 逻辑:直接检查嵌套父目录中是否存在 package.json。

更严格的解析

Vite 必须调用 Nodejs fs API 来查找模块。但是 IO 很昂贵。Vite 4.3 缩小了文件搜索范围,并跳过搜索一些特殊路径,以尽可能减少 fs 调用。例如:

  1. 由于 # 符号不会出现在 URL 中,用户可以控制源文件路径中没有 # 符号,因此 Vite 4.3 不再检查用户源文件中带有 # 符号的路径,而是仅在 node_modules 中搜索它们。
  2. 在Unix系统中,Vite 4.2 会先检查根目录下的每一个绝对路径,对大多数路径都可以,但是如果绝对路径以根开头就很容易失败。为了在 /root/root 不存在的情况下跳过搜索 /root/root/path-to-file,Vite 4.3 会在开头判断 /root/root 作为目录是否存在,并预先缓存结果。
  3. 当 Vite 服务器收到 @fs/xxx​ 和 @vite/xxx 时,就不需要再解析这些 URL。Vite 4.3 直接返回之前缓存的结果,不再重新解析。

更准确的解析

Vite 4.2 在文件路径为目录时递归解析模块,会导致不必要的重复计算。Vite 4.3 将递归解析扁平化,并对不同类型的路径应用适当的解析,展平后缓存一些 fs 调用也更容易。

包解析

Vite 4.3 打破了解析 node_modules 包数据的性能瓶颈。Vite 4.2 使用绝对文件路径作为包数据缓存键。这还不够,因为 Vite 必须遍历 pkg/foo/bar​ 和 pkg/foo/baz 中的同一个目录。

Vite 4.3 不仅使用了绝对路径(/root/node_modules/pkg/foo/bar.js​ & /root/node_modules/pkg/foo/baz.js​),还使用了遍历目录(/root/node_modules/pkg/foo​ & /root/node_modules/pkg​) 作为 pkg 缓存的键。

另一种情况是,Vite 4.2 在单个函数中查找深层导入路径的 package.json​,例如 Vite 4.2 解析 a/b/c/d​ 等文件路径时,首先检查根 a/package.json​ 是否存在, 如果没有,则按照a/b/c/package.json​ -> a/b/package.json​的顺序查找最近的package.json​,但事实是查找根package.json​和最近的package.json​应该分开处理 ,因为在不同的解析上下文中需要它们。Vite 4.3 将根 package.json​ 和最近的 package.json 解析分成两部分,这样它们就不会混在一起。

fs.realpathSync 问题

Nodejs 中有一个有趣的 realpathSync 问题,它指出 fs.realpathSync​ 比 fs.realpathSync.native​ 慢 70 倍。但 Vite 4.2 仅在非 Windows 系统上使用 fs.realpathSync.native​,因为它在 Windows 上的行为不同。为了解决这个问题,Vite 4.3 在 Windows 上调用 fs.realpathSync.native 时添加了网络驱动器验证。

非阻塞任务

作为一个按需服务,Vite dev server 可以在没有准备好所有东西的情况下启动。

非阻塞 tsconfig 解析

Vite 服务器在预绑定 ts 或 tsx 时需要 tsconfig 数据。

Vite 4.2 在服务端启动之前,在插件钩子 configResolved​ 中等待 tsconfig​ 数据解析完成。一旦服务器启动而没有准备好 tsconfig​ 数据,页面请求就可以访问服务器,即使请求可能需要稍后等待 tsconfig 解析。

Vite 4.3 会在服务器启动前初始化 tsconfig​ 解析,但服务器不会等待。解析过程在后台运行。一旦有ts相关的请求进来,就得等tsconfig解析完了。

非阻塞文件处理

Vite 中有大量的 fs 调用,其中一些是同步的。这些同步 fs 调用可能会阻塞主线程。Vite 4.3 将它们改为异步。此外,并行化异步函数也更容易。关于异步函数,可能有许多 Promise 对象在解析后要释放。由于更智能的解析策略,释放 fs-Promise 对象的成本要低得多。

HMR 防抖

考虑两个简单的依赖链 C <- B <- A & D <- B <- A,当 A 被编辑时,HMR 将从 A 传播到 C 和 A 传播到 D。这导致 A 和 B 在 Vite 4.2 中被更新两次。

Vite 4.3 缓存了这些遍历的模块,以避免多次搜索它们,它适用于由 git checkout 触发的 HMR。

并行化

并行化始终是获得更好性能的好选择。在 Vite 4.3 中,我们并行化了一些核心功能,包括导入分析、提取 deps 的导出、解析模块 url 和运行批量优化器。

Javascript 优化

用回调替换 *yield

Vite 使用 tsconfck​ 来查找和解析 tsconfig​ 文件。tsconfck​ 曾经通过 *yield​ 遍历目标目录,生成器的一个缺点是它需要更多的内存空间来存储它的生成器对象,并且在运行时会有大量的生成器上下文切换。所以从 v2.1.1 开始在核心中用回调替换 ​​*yield​​。

使用 === 代替 startsWith 和 endsWith

Vite 4.2 使用 startsWith​ 和 endsWith​ 检查热更新 URL 中的头部和尾部 '/'。比较 str.startsWith('x')​ 和 str[0] === 'x'​ 的执行基准发现,===​ 比 startsWith​ 快约 20%,endsWith 比 === 慢约 60%。

避免重复创建正则表达式

Vite 需要很多正则表达式来匹配字符串,其中大部分都是静态的,因此只使用它们的单例会更好。Vite 4.3 将正则表达式提升,以便可以重复使用它们。

放弃生成自定义错误

在 Vite 4.2 中,有一些自定义错误以改进开发体验。这些错误可能会导致额外的计算和垃圾回收,从而降低 Vite 的速度。在 Vite 4.3 中,放弃了生成某些热更新自定义错误(例如 package.json NOT_FOUND 错误),直接抛出原始错误以获得更好的性能。

参考资料:

  • https://vitejs.dev/blog/announcing-vite4-3.html。
  • https://sun0day.github.io/blog/vite/why-vite4_3-is-faster.html。

有关Vite 4.3 正式发布,速度全面提升!的更多相关文章

  1. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  2. ruby-on-rails - 如何在发布新的 Ruby 或 Rails 版本时收到通知? - 2

    有人知道在发布新版本的Ruby和Rails时收到电子邮件的方法吗?他们有邮件列表,RubyonRails有一个推特,但我不想听到那些随之而来的喧嚣,我只想知道什么时候发布新版本,尤其是那些有安全修复的版本。 最佳答案 从therailsblog获取提要.http://weblog.rubyonrails.org/feed/atom.xml 关于ruby-on-rails-如何在发布新的Ruby或Rails版本时收到通知?,我们在StackOverflow上找到一个类似的问题:

  3. ruby-on-rails - 如果条件与 &&,是否有任何性能提升 - 2

    如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:

  4. ruby-on-rails - 获取 ActionController::RoutingError(当尝试使用 AngularJS 将数据发布到 Rails 服务器时,没有路由匹配 [OPTIONS] "/users" - 2

    尝试从我的AngularJS端将数据发布到Rails服务器时出现问题。服务器错误:ActionController::RoutingError(Noroutematches[OPTIONS]"/users"):actionpack(4.1.9)lib/action_dispatch/middleware/debug_exceptions.rb:21:in`call'actionpack(4.1.9)lib/action_dispatch/middleware/show_exceptions.rb:30:in`call'railties(4.1.9)lib/rails/rack/logg

  5. 映宇宙2022年营收63亿元:同比下降三成,毛利率提升4.3个百分点 - 2

    3月26日,映宇宙(HK:03700,即“映客”)发布截至2022年12月31日的2022年度业绩财务报告。财报显示,映宇宙2022年的总营收为63.19亿元,较2021年同期的91.76亿元下降31.1%。2022年,映宇宙的经营亏损为4698.7万元,2021年同期则为净利润4.57亿元;期内亏损(净亏损)为1.68亿元,2021年同期的净利润为4.33亿元;非国际财务报告准则经调整净利润为3.88亿元,2021年同期为4.82亿元,同比下降19.6%。 映宇宙在财报中表示,收入减少主要是由于行业竞争加剧,该集团对旗下产品采取更为谨慎的运营策略以应对市场变化。不过,映宇宙的毛利率则有所提升

  6. iNFTnews | 周杰伦18年前未发布的作品Demo,藏在了区块链技术里 - 2

    当音乐碰上区块链技术,会擦出怎样的火花?或许周杰伦已经给了我们答案。8月29日下午,B站独家首发周杰伦限定珍藏Demo独家访谈VCR,周杰伦在VCR里分享了《晴天》《青花瓷》《搁浅》《爱在西元前》四首经典歌曲Demo背后的创作故事,并首次公布18年前未发布的神秘作品《纽约地铁》的Demo。在VCR中,方文山和杰威尔音乐提及到“多亏了区块链技术,现在我们可以将这些Demos,变成独一无二具有收藏价值的艺术品,这些Demos可以在薄盒(国内数藏平台)上听到。”如何将音乐与区块链技术相结合,薄盒方面称:“薄盒作为区块链技术服务方,打破传统对于区块链技术只能作为数字收藏的理解。聚焦于区块链技术赋能,在

  7. java - Ruby 和 Java 的速度 - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。在我在网上找到的每个基准测试中,Ruby似乎都很慢,比Java慢得多。Ruby的人只是说这无关紧要。您能举个例子说明RubyonRails(以及Ruby本身)的速度真的无关紧要吗?

  8. ruby - 如何在 Ruby 中从内存中 HTTP 发布流数据? - 2

    我想上传我在运行时用Ruby生成的数据,就像从block中提供上传数据一样。我找到的所有示例仅展示了如何流式传输必须在请求之前位于磁盘上的文件,但我不想缓冲该文件。除了滚动我自己的套接字连接之外,最好的解决方案是什么?这是一个伪代码示例:post_stream('127.0.0.1','/stream/')do|body|generate_xmldo|segment|body 最佳答案 有效的代码。require'thread'require'net/http'require'base64'require'openssl'class

  9. IDEA 2023.1 正式发布,新特性简介 - 2

     昨晚看到IDEA官推宣布IntelliJIDEA2023.1正式发布了。简单看了一下,发现这次的新版本包含了许多改进,进一步优化了用户体验,提高了便捷性。至于是否升级最新版本完全是个人意愿,如果觉得新版本没有让自己感兴趣的改进,完全就不用升级,影响不大。软件的版本迭代非常正常,正确看待即可,不持续改进就会慢慢被淘汰!根据官方介绍:IntelliJIDEA2023.1针对新的用户界面进行了大量重构,这些改进都是基于收到的宝贵反馈而实现的。官方还实施了性能增强措施,使得Maven导入更快,并且在打开项目时IDE功能更早地可用。由于后台提交检查,新版本提供了简化的提交流程。IntelliJIDEA

  10. Unity数据可视化图表插件XCharts3.0发布 - 2

    Unity数据可视化图表插件XCharts3.0发布历时8个多月,业余时间,断断续续,XCharts3.0总算发布了。如果要打个满意度,我给3.0版本来个80分。对于代码框架结构设计的调整改动,基本符合预期,甚是满意。相比之前的1.0和2.0版本,我认为3.0才是一个拿得出手给广大开发者使用的版本。1.0发布的时候,很兴奋,从0.1到1.0,也磨了一年,真的等不及想给大家试用了,还特地写过一篇文章以示庆祝。那个时候,1.0虽然还还不够完善,功能也不够丰富,但它是XCharts的开始,没有1.0,也就没有后面的2.0和3.0。后面的2.0发布,做了很多改进和优化,随着版本迭代,慢慢的发现有不少硬

随机推荐