type
status
date
slug
summary
tags
category
icon
password

前言

vite比webpack快?
vite比webpack简单?
今天我们就来分析一下,到底有什么不一样的地方!

定位

对比之前,我们先要搞懂,vite与webpack的定位以及关系才可以。
那前端社区中常谈到的这些工具webpackrollupparcelesbuildvitevue-clicreate-react-appumi他们之间的关系是怎样的。
  • webpackrollupparcelesbuild都是打包工具,代码写好之后,我们需要对代码进行压缩合并转换分割打包等操作,这些工作需要打包工具去完成。
  • vue-clicreate-react-appumi 是基于webpack的上层封装,通过简单的配置就可以快速创建出一个项目,把更多的时间放在业务开发上。
  • vite开发环境依赖esbuild进行预构建,生产环境则依赖rollup进行打包,并且充分利用了现代浏览器的特性,比如http2ES modulevite是站在众多巨人肩膀上的一个产物, 类似webpack + webpack-dev-server的结合体,是一个非常棒的前端项目的构建工具。

运行原理

首先,我们从运行原理上分析一下,vite为什么比webpack快。
webpack运行原理
notion image
当我们使用webpack启动项目时,webpack会根据我们配置文件(webpack.config.js) 中的入口文件(entry),分析出项目项目所有依赖关系,然后打包成一个文件(bundle.js),交给浏览器去加载渲染。
这样就会带来一个问题,项目越大,需要打包的东西越多,启动时间越长。
关于ES module
在讲vite运行原理之前,我们先说一下ES module
目前,绝大多数现代浏览器都已经支持ES module了, 我们只需要在<script>标签中添加type="module",就可以使用ES module了。
下面这段代码是可以直接在浏览器中运行的。
vite运行原理
notion image
<script type="module">中,浏览器遇到内部的import引用时,会自动发起http请求,去加载对应的模块。
vite也正是利用了ES module这个特性,使用vite运行项目时,首先会用esbuild进行预构建,将所有模块转换为es module,不需要对我们整个项目进行编译打包,而是在浏览器需要加载某个模块时,拦截浏览器发出的请求,根据请求进行按需编译,然后返回给浏览器。
这样一来,首次启动项目(冷启动)时,自然也就比webpack快很多了,并且项目大小对vite启动速度的影响也很小。

构建方式

我们再来看一下,vite与webpack在项目构建上有哪些区别。
webpack
webpack是基于nodejs运行的,但js只能单线程运行,无法利用多核CPU的优势,当项目越来越大时,构建速度也就越来越慢了。
vite
vite预构建按需编译的过程,都是使用esbuild完成的。
esbuild是用go语言编写的,可以充分利用多核CPU的优势,所以vite开发环境下的预构建按需编译速度,都是非常快的。

http2

vite充分利用了http2可以并发请求的优势,这也是速度快的一个主要原因。 接下来,我们了解一下http2的来龙去脉。
在之前http1的时候,浏览器对同一个域名的请求,是有并发限制的,一般为6个,如果并发请求6个以上,就会造成阻塞问题,所以在http1的时代,我们要减少打包产物的文件数量,减少并发请求,来提高项目的加载速度。
2015年以后,http2出现了,他可以并发发送多个请求,不会出现http1的并发限制。这时候,将打包产物分成多个小模块,并行去加载,反而会更快。
vite也充分利用了这一优势,对项目资源进行了合理的拆分,访问项目时,同时加载多个模块,来提升项目访问速度。

热更新

vite速度快的另一个原因是与webpack不同的热更新机制。
我们首先来了解一下什么是HMR。
模块热替换(hot module replacement - HMR),该功能可以实现应用程序运行过程中,替换、添加或删除模块,而无需重新加载整个页面,也就是我们常说的热更新
vite与webpack虽然都支持HMR,但两个工具的实现原理是不一样的。
webpack
webpack项目中,每次修改文件,都会对整个项目重新进行打包,这对大项目来说,是非常不友好的。
虽然webpack现在有了缓存机制,但还是无法从根本上解决这个问题。
vite
vite项目中,监听到文件变更后,会用websocket通知浏览器,重新发起新的请求,只对该模块进行重新编译,然后进行替换。
并且基于es module的特性,vite利用浏览器的缓存策略,针对源码模块(我们自己写的代码)做了协商缓存处理,针对依赖模块(第三方库)做了强缓存处理,这样我们项目的访问的速度也就更快了。

生产环境

vite生产环境下,为什么使用rollup打包呢?
Rollup 是一款 ES Module 打包器, 从作用上来看,RollupWebpack 非常类似。不过相比于 WebpackRollup要小巧的多,打包生成的文件更小。 因为小巧,自然在这种特定的打包环境下,Rollup的打包速度也要比 Webpack 快很多。
vite正是基于es module的特性实现的,所以使用rollup要更合适一些。
vite生产环境下,为什么不用esbuild打包呢?
尽管esbuild的打包速度比rollup更快,但 Vite 目前的插件 API 与使用 esbuild 作为打包器并不兼容,rollup插件api与基础建设更加完善,所以在生产环境vite使用rollup打包会更稳定一些。
如果后面esbuild基础建设与生态更加完善后,esbuild还是更有优势的。
所以使用vite可能会带来开发环境与生产环境打包结果不一致的问题。

使用成本

除了速度上的区别,我们再分析一下,vite与webpack的使用成本。
webpack
如果我们使用webpack自己去搭建项目脚手架时,需要配置比较多的东西, 比如:跨域代码压缩代码分割css预处理器的代码转换样式兼容性vue/react代码解析图片压缩代码热更新es降级ts转换等等,远不止这些。
概念和配置项太多,我们需要了解各种loader、plugin的使用,并且需要根据项目场景,对配置不断进行优化,心智负担太大。
所以就出现了一些基于webpack上层封装的脚手架,如:vue-clicreate-react-appumi等。
vite
vite对我们常用功能都做了内置,比如:css 预处理器html 预处理器hash 命名异步加载分包压缩HMR等等,我们可以很轻松的通过配置项去配置。
并且vite官方也提供了一些官方模板、社区模板,我们可以快速地创建出一个带有最佳预设项目,不需要关心太多的配置项。
vite的出现,降低了我们的学习成本、增加了开发体验,我们就可以把更多的时间放在业务开发上了,打磨出更好产品。
 
精读React hooks(一):useState 的几个基础用法和进阶技巧elm级联选择器父节点单选,子节点多选