Vite为什么快?快在哪?

282 阅读2分钟

问题现状

ES模块化支持的问题

众所周知,以前的浏览器是不支持ES module的,如


// index.js




import { add } from './add.js'

import { sub } from './sub.js'

console.log(add(1, 2))

console.log(sub(1, 2))




// add.js

export const add = (a, b) => a + b




// sub.js

export const sub = (a, b) => a - b

上面的一段代码,放在浏览器不能直接运行。于是,就出现了打包工具,他将index.js、add.js、sub.js三个文件打包在一个bundle.js文件中,然后在index.html中引入bundle.js,从而达到代码效果。如webpack、Rollup、Parcel

项目启动与代码更新的问题

  • 项目启动:随着项目越来越大,启动项目可能要几分钟

  • 代码更新:随着项目越来越大,修改一小段代码,保存后要等几秒才更新

解决问题

解决项目启动缓慢

Vite在打包的时候,将模块分成两个区域依赖源码

  • 依赖:指在开发中不会改变的js依赖包,此部分使用esbuild来进行预构建依赖。由于esbuild使用的是Go语言编写,比js编写的打包器预构建依赖快10-100倍

  • 源码:指修改几率比较大且需转换的文件,如JSX、css、vue。同时,这些文件也不是全部加装,而是按需加载(路由懒加载)。Vite将文件转换后,以es module的方式直接交给浏览器。

第一张图,是以前的打包模式,项目启动时,需先将所有文件打包成一个bundle.js,然后在html引入,这个多文件->bundle.js的过程是非常耗时间的。

第二张图,是Vite的打包方式,Vite是直接把转换后的es module的js代码,扔给支持es module的浏览器,让浏览器去加载依赖,即把压力转给浏览器,从而达到启动速度快的效果

解决更新缓慢

项目启动时,将模块分成依赖源码,当更新代码时,依赖就不需要重新加载,只需精准地找到哪个源码文件更新了,更新相对应的文件就行了。这样做使得更新速度非常快。

Vite 同时利用 HTTP头来加速整个页面的重新加载,源码模块的请求会根据304 Not Modified进行协商缓存,而依赖模块请求则会通过Cache-Control: max-age=3153600,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求

生产环境

生产环境不像开发环境,直接开个Vite服务就行

  • 若代码放服务器,过多的浏览器加载依赖肯定会引起更多的网络请求

  • 最佳的加载性能:代码进行tree-shaking、懒加载和chunk分割、CSS处理,这些优化操作,目前esbuild还不完善

所以Vite最后的打包是使用了Rollup