Vite为什么比Webpack快

本文作者为 360 奇舞团前端开发工程师

一.引言

Vite和Webpack作为两个主流的前端构建工具,在近年来备受关注。它们的出现使得前端开发变得更加高效和便捷。然而,随着前端项目规模的不断增大和复杂度的提升,构建工具的性能优化也成为了开发者关注的焦点。在性能方面,Vite相比于Webpack表现出了明显的优势,尤其是在本地开发时冷启动速度、HMR性能和构建速度等方面。本文将深入解析Vite为什么比Webpack更快的原因,并探讨其背后的技术实现。

二.构建方式

1.Webpack

3909a70b718a49929e9755bb5c335221.jpeg
image-20240310161017787

上图是Webpack在本地启动项目时的一个过程表示,当你使用 Webpack 打包一个项目时,通常会生成一个或多个 bundle 文件,这些文件包含了你的应用程序所需的所有代码、样式和资源。然后,你可以在 HTML 文件中通过 <script> 标签引入这些 bundle 文件,从而加载你的应用程序。但是随着项目规模的增大,通常会有更多的模块需要打包。Webpack 需要扫描整个项目的依赖图,并分析模块之间的依赖关系,这个过程会变得更加复杂和耗时。

2.vite

44e6c554d51b4cb3b134d363def911aa.jpeg

我们通过上图,可以看到本地启动一个Vite项目时,和Webpack有一些不一样了,Server服务一开始就启动,然后通过网络请求去加载对应了文件。Vite的构建特点,我们可以用下面几点来概括。

基于浏览器原生 ES 模块支持:Vite 利用了现代浏览器对 ES 模块(ESM)的原生支持,采用的是一种no bundle的策略,当使用 Vite 启动项目时,它会将每个模块都作为一个独立的文件提供给浏览器,而不需要像传统的打包工具(如 Webpack)那样先将模块打包成一个或多个 bundle。这样一来,浏览器可以更快地加载和解析这些模块,从而实现了快速的冷启动速度。

即时编译(Instant Compilation):Vite 采用了即时编译策略。当浏览器请求一个模块时,Vite 会即时地将该模块编译成浏览器可执行的代码,并将编译结果缓存起来(我们在node_modules下可以找到一个.vite文件)。下次再次请求同一模块时,Vite 可以直接返回缓存的编译结果,而不必重新编译,从而避免了冗余的编译过程,大大提高了启动速度。

esbuild预构建依赖:Go 语言编写的快速、轻量级的 JavaScript/TypeScript 构建工具,比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。

三.热更新

Webpack 的热更新机制是通过 webpack-dev-server 提供的功能来实现的。webpack-dev-server 是一个开发服务器,用于在开发过程中提供快速的开发体验,包括热更新、自动刷新等功能。

Webpack-dev-server 的热更新机制是基于 WebSocket 技术实现的。当你启动 webpack-dev-server 时,它会创建一个 WebSocket 服务器,与浏览器端建立连接。然后,webpack-dev-server 会监视项目文件的变化,并将这些变化推送给浏览器端,浏览器端收到变化后会执行相应的更新操作,从而实现了热更新的效果。

具体来说,webpack-dev-server 的热更新机制包括以下几个步骤:

  1. 创建 WebSocket 服务器:webpack-dev-server 在启动时会创建一个 WebSocket 服务器,并与浏览器端建立连接。

  2. 监听文件变化:webpack-dev-server 会监听项目文件的变化,包括入口文件、模块文件、样式文件等。

  3. 构建更新模块:当文件发生变化时,webpack-dev-server 会重新构建变化的模块,并生成更新的代码。

  4. 推送更新信息:webpack-dev-server 将更新的模块信息通过 WebSocket 推送给浏览器端。

  5. 浏览器端处理更新:浏览器端接收到更新信息后,会根据更新的模块信息执行相应的更新操作,例如重新加载模块、更新页面内容等。

而Vite 也使用了 WebSocket 技术来实现与浏览器的通信。当有模块变化时,Vite 会通过 WebSocket 将更新信息推送给浏览器端,从而触发浏览器端的模块重载。这样看起来,它和Webpack似乎没有什么不同,但是根据Vite官网的说法,在 Vite 中,HMR 是在原生 ESM 上执行的。当编辑一个文件时,Vite 只需要精确地使已编辑的模块与其最近的 HMR 边界之间的链失活(大多数时候只是模块本身),使得无论应用大小如何,HMR 始终能保持快速更新。从官网的解释中我们可以理解为,Vite因为支持ESM的能力,使得它比Webpack拥有更小粒度的热更新能力。

四.生产环境

在生产环境下,二者的打包,构建时间就没有这么大的区别了,因为在生产环境下Vite仍需要通过Rollup将代码打包。主要是基于以下几点考虑。

  1. 兼容性:尽管现代浏览器对 ESM 模块有很好的支持,但在生产环境中仍然需要考虑到旧版浏览器的兼容性。为了确保应用在所有浏览器中都能正常运行,需要将 ESM 模块转换成兼容性更好的 JavaScript 代码,通常是通过打包工具进行转换和优化。

  2. 性能优化:在生产环境中,需要对代码进行一些性能优化,如代码压缩、合并、分割等,以减小代码体积、加快页面加载速度。通过打包工具,可以将多个模块合并成一个或多个 bundle,并对代码进行压缩和混淆,以减小文件体积。

  3. 资源管理:除了 JavaScript 代码外,现代的前端应用还包含许多其他类型的资源,如样式表、图片、字体等。打包工具可以帮助管理这些资源,将它们进行优化、压缩,并生成适当的 URL 地址,以便在生产环境中有效地加载和使用这些资源。

  4. 部署和发布:在生产环境中,需要将应用部署到服务器上,并且通常会对代码进行一些配置和优化。通过打包工具,可以方便地生成部署所需的静态文件,并进行一些配置,如路径设置、缓存控制等,以便于部署和发布应用。

五.总结

Vite在本地能更快的根本原因,是借用了浏览器原生ESM能力,从而跳过了生成bundle的时间,再加上能够不依赖第三方插件将编译结果缓存,而且esbuild自身的也有着更快的运行速度,从而实现了Vite快速的冷启动。

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

f57b9037408b20f6f9306655d689873c.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/536800.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Mac】鼠标控制\移动\调整窗口大小BBT|边缘触发调整音量\切换桌面

一直在 win 习惯了通过鼠标的侧键来控制窗口的位置、大小&#xff0c;现在找到心的解决方案了&#xff0c;通过 BBT 设置侧键按下\抬起几颗。 以下解决方案的截图&#xff0c;其中还包括了其他操作优化方案&#xff1b; 滚轮配合 cmd 键调节页面大小&#xff1b;配合 option 键…

Docker拉取镜像存储不足

在使用Docker时&#xff0c;我们经常遇到一个问题&#xff0c;就是拉取镜像时提示存储空间不足。这是因为Docker在拉取镜像时需要将镜像文件下载到本地存储中&#xff0c;而有时本地存储空间不足以容纳完整的镜像文件。 本文将介绍一些解决这个问题的方法&#xff0c;并提供相…

简单理解NAT模式和桥接模式

目录 桥接模式NAT模式总结 桥接模式 1.桥接模式下 当物理机X创建了一台或多台虚拟机 那么这些创建出来的虚拟机 可以视作一台独立的新机器 加入了该局域网 并允许和该局域网的物理机或者其他虚拟机直接通信 2.问题一在于 C类网的分配是有范围的(0-255) 假如是一个教室里的局域…

Java集合基础知识总结(绝对经典)

List接口继承了Collection接口&#xff0c;定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理&#xff0c;还添加了面向位置的操作。 实际上有两种list&#xff1a;一种是基本的ArrayList&#xff0c;其优点在于随机访问元素&#xff0c;另一种是更强大的L…

20240313寻找集成联调交付的具体方式

集成联调交付&#xff08;Integrated Joint Debugging and Delivery&#xff09;是软件开发过程中的一个阶段&#xff0c;主要涉及将不同的软件模块或组件整合在一起&#xff0c;并进行联合调试和测试&#xff0c;以确保它们能够作为一个整体正常工作。这个过程通常发生在开发周…

Parade Series - WebRTC ( < 300 ms Low Latency )

Parade Series - FFMPEG (Stable X64) C:\Conda\parading-cam>ffmpeg -f dshow -i video"Surface Camera Front" -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -an -rtsp_transport tcp -f rtsp://127.0.0.1:8554/cam0801

十三届 试题A(星期计算)

已知今天是星期六&#xff0c;请问 20的22次方 天后是星期几&#xff1f; 注意用数字 1 到 7 表示星期一到星期日。 解题思路&#xff1a; 算出20的22次方&#xff0c;并对它求余&#xff0c;所得余数加上6&#xff0c;在往后推算看是星期几。 解题代码&#xff1a; public c…

记录一下在Pycharm中虚拟环境的创建

如果在Pycharm中要新建一个虚拟环境&#xff0c;那你可以在Terminal中选择Command Prompt&#xff0c;在这里面执行相关命令 一、安装了Anaconda&#xff0c;创建虚拟环境 当你使用解释器是Anaconda提供的时&#xff0c;你可以使用conda命令执行&#xff0c;见以下操作&#x…

vue学习笔记24-组件事件配合v-model使用

搜索时v-model绑定的search数据时时发生变化 watch侦听器时时监察变化&#xff0c;一旦数据发生变化 &#xff0c;就实时发送数据给父组件 子组件的完整代码&#xff1a; <template>搜索&#xff1a;<input type"text" v-model"search"> <…

力扣654 最大二叉树 Java版本

文章目录 题目描述解题思路代码 题目描述 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大值 右边 的 子数组后缀上…

Set cancelled by MemoryScratchSinkOperator

Bug信息 Caused by: com.starrocks.connector.spark.exception.StarrocksInternalException: StarRocks server StarRocks BE{host=10.9.14.39, port=9060} internal failed, status code [CANCELLED] error message is [Set cancelled by MemoryScratchSinkOperator]Bug产生的…

如何“使用Docker快速安装Jenkins,在CentOS7”?

1、运行 docker run -d --namejenkins -p 8080:8080 jenkins/jenkins 2、查看日志 &#xff0c;使用 "docker logs -f jenkins",可以持续刷新日志 docker logs jenkins 3、通过命令查看密码 docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminP…