应届毕业刚进项目组接手的就是一个Vite构建的React项目,项目刚搭建的时候就是抛弃了Webpack使用的Vite,本地启动速度确实比Webpack快了不少。由此引发第一个问题,vite为什么比webpack快?
一、Vite为什么比Webpack快?
-
Bundle or Bundleless?
Bundle指的就是打包构建,与无打包构建Bundleless相对应。Webpack是标准的Bundle模式,无论是项目启动还是文件变更,都需要走一遍完整的打包流程。所以即使只修改了一行代码,也需要经历一遍完整的依赖分析,代码转译和打包。即使webpack可以通过bundle splitting,在一定程度上缓解这个问题。即将一个文件分为多个文件,当你修改一个文件中的代码时,用户只需要下载被修改的那个文件,其他文件可以在浏览器缓存中加载。但整个流程的颗粒度仍较大。
而Vite是Bundleless模式,在认识Bundleless之前需要理解什么是打包?之前为什么需要打包?这里的打包是指Bundle而不是我们常说的npm包管理器中的package,package是指封装好的且具有特定功能的整体代码,比如npm里面各种的第三方库;而Bundle是指把多个文件合成一个文件。
1、打包通过合并文件可以有效减少http的请求数量,从而加快页面的加载速度。这也是常见的性能优化手段。在HTTP/1.1中各个浏览器有并行连接限制,常见的浏览器如Chrome、Edge和Firefox都是限制6个,因此通过打包手段减少http的请求数量是有必要的。而在HTTP/2中引入了多路复用的概念,即可以在一个TCP连接中同时接受和发送多个请求。因此通过打包来减少网络请求数量从而提高性能的手段变得不那么必要。 2、JS的模块化能够让我们更好的组织和维护函数和变量,常见的JS模块有CJS、AMD、CMD、UMD等,而CommonJS不能直接运行在浏览器环境,需要通过打包将其转换成可以在浏览器运行的js文件,而现在各大主流浏览器已逐渐支持ESM的开发模式,借助浏览器ESM的能力,一些代码基本上可以做到无需构建直接运行。因此ESM已经成为现如今js最常见的模块规范,且之前因为CJS而要进行打包的操作也变得不那么必要。 由上可以知道,Bundleless是基于打包过程必要性降低而出现的,ESM成为未来趋势也是Bundless流行的一大推手。
所以在实现方式上Bundleless相比于Bundle模式省去大量步骤,而基于Bundleless模式的Vite自然要比Webpack要快。
二、双引擎架构的Vite
Vite底层使用了两个构建引擎,即esbuild和Rollup。简单来说也就是开发环境使用esbuild,生产环境使用Rollup,这样双架构设计的目的是什么?
1. esbuild——性能优异的JS构建工具
1.1 开发阶段的预构建依赖
即在项目启动或者构建之前,将项目中所需的依赖提前进行处理或者构建,这样的好处是当项目实际运行时,可以直接使用构建好的依赖,无需进行实时的编译或者构建。Vite基于esbuild进行预构建依赖,而不是传统的webpack/Rollup。esbuild作为一款由golang语言开发的构建工具,可以充分利用多核CPU的优势,其响应速度是纳秒级的,而基于NodeJs编写的WebPack远远达不到使用esbuild的Vite的速度。