Vite为什么这么快

本文代码仓库:https://gitee.com/dongyuanxin/learn-vite

认识Vite

vite本身是个前端编译工具的聚合器。内部使用了rollup、babel等工具,来达到特定场景下提高构建速度的效果。

构建工具

根据不同的环境,vite会使用不同的底层构建工具:

  • 开发环境:
    • ES Build:基于golang 的 javascript 打包工具,速度更快,可以实现rollup、webpack的大部分功能。
  • 生产环境:
    • Rollup:成熟和稳定是关键,而不是编译速度

代码类型

根据代码变动的频繁程度,vite将代码分为2类:

  • 依赖:第三方库,不变动,代码多,数量大。
  • 源码:项目代码,变动频繁,经常修改。

预构建

对于「依赖」代码,vite采用了 pre-bundle(预编译)的做法:

  • 在“冷启动”时,使用esbuild对依赖进行编译,并且将其放入到 .vite 目录下
  • 在没有新的依赖更新的情况下,再次启动时,会直接使用前一步构建好的依赖

ESM

vite基于现代浏览器原生的ESM能力,来避免了像webpack那样(对整个源码进行遍历,转换成AST,然后再打包成多份javascript),大大提高了开发模式下的编译速度。

Untitled.png

上面的2张图中,左侧是源码,右侧是访问构建好的网站。

注意看右图的绿色框部分,里面的代码基本没变化,几乎就是左侧源码直出。

并且使用了 import 语法,这里也没进行任何转换,完全依赖浏览器的ESM能力。

需要注意的是,不论是「源码」还是「依赖」,它们的路径都被转换了。因为ESM不能直接使用本地的路径,所以vite内部还架设了一个 koa.js 服务器,就是单纯做静态服务,将路径进行转换。

这样,不论项目多么复杂,都不会增加编译耗时,因为其速度完全取决于 koa.js 静态服务和浏览器自带的ESM。

如果是webpack,项目复杂后,代码分析、ast转换、生成目标代码,这3步的耗时就会快速增加。

HTTP缓存

对于不同类型的代码,在开发模式采用了不同的http缓存策略:

  • 依赖:强制缓存

    Untitled.png

  • 源码:协商缓存

    Untitled.png

这算是优化的小tips,但不是提速的核心,核心还是「预构建」+「ESM」

参考文档

Untitled

bookmark

bookmark

bookmark

bookmark