一、前言
这三者的定位都有些不同,不好直接比较,但是做的事情还算类似,因此放一块拿来说说。vite 是新生技术,由其快速优秀的开发体验有取代 webpack 的趋势,但是它并不如 webpack 打包工具那么灵活,vite 内部的打包工具是采用的 esbuild,其性能之高也来自于此。
二、Vite2.0 特性
- 基于 esbuild 实现的极速开发体验
- 多框架支持
- 兼容 Rollup 的插件机制与 API
- SSR 支持
- 旧浏览器支持
三、在启动时,vite 为何比 webpack 快那么多?
主要是 Vite 在开发模式没有做太多打包操作
Webpack 启动后会做一堆事情,经历一条很长的编译打包链条,从入口开始需要逐步经历语法解析、依赖收集、代码转译、打包合并、代码优化,最终将高版本的、离散的源码编译打包成低版本、高兼容性的产物代码,这可满满都是 CPU、IO 操作啊,在 Node 运行时下性能必然是有问题。
而 Vite 运行 Dev 命令后只做了两件事情,一是启动了一个用于承载资源服务的 service;二是使用 esbuild 预构建 npm 依赖包。之后就一直躺着,直到浏览器以 http 方式发来 ESM 规范的模块请求时,Vite 才开始“「按需编译」”被请求的模块。
这里 Vite 预设的前提是:
- 现代浏览器大多数已经原生支持 ESM 规范,构建工具 —— 特别是开发环境下已经没有太大必要为了低版本兼容把大量的时间花在编译打包上了!
这么一对比,Webpack 是啥都做了,浏览器只要运行编译好的低版本(es5)代码就行;而 Vite 只处理问题的一部分,剩下的事情交由浏览器自行处理,那速度必然贼 TM 快。
除了启动阶段跳过编译操作之外,Vite 还有很多值得一提的性能优化,整体梳理一下:
- 预编译:npm 包这类基本不会变化的模块,使用 Esbuild 在 「预构建」 阶段先打包整理好,减少 http 请求数
- 按需编译:用户代码这一类频繁变动的模块,直到被使用时才会执行编译操作
- 客户端强缓存:请求过的模块会被以 http 头
max-age=31536000,immutable
设置为强缓存,如果模块发生变化则用附加的版本 query 使其失效 - 产物优化:相比于 Webpack ,Vite 直接锚定高版本浏览器,不需要在 build 产物中插入过多运行时与模板代码
- 内置更好的分包实现:不需要用户干预,默认启用一系列智能分包规则,尽可能减少模块的重复打包
- 更好的静态资源处理:Vite 尽量避免直接处理静态资源,而是选择遵循 ESM 方式提供服务,例如引入图片
import img from 'xxx.png'
语句,执行后img
变量只是一个路径字符串。
vite 的优点
简单:
vite 预设的开发环境就内置了
- css 预处理器
- html 预处理器
- HMR 支持
- 异步加载
- 默认分包
- 默认 chunk hash 重命名
比起 webpack 的各种配置项和插件,虽然不够灵活,但是方便很多,大概是本身的定位就不是同一种东西,webpack 是打包工具,而 vite 是一套能够显著提升前端开发体验的前端构建工具。
缺点
兼容性:
要求客户端的浏览器是比较新的版本,不去兼容那些落伍的浏览器才能做到如此快速方便,如果项目需要支持老旧的浏览器,就不要用 vite 了。
四、ESbuild
Esbuild 是一个非常新的模块打包工具,它提供了与 Webpack、Rollup、Parcel 等工具「相似」的资源打包能力,却有着高的离谱的性能优势。
为什么快?
-
语言优势:使用的是 go 语言,性能上具有优势。JavaScript 是解释型语言,而 go 是编译型语言。在打包场景上,差距就比较明显了。JavaScript 运行时还在解释代码的时候,Esbuild 已经在解析用户代码;JavaScript 运行时解释完代码刚准备启动的时候,Esbuild 可能已经打包完毕,退出进程了!
-
多线程优势:Go 天生能多线程运行,而 JavaScript 本身是单线程语言,在引入 webworker 后才能在浏览器、node 中实现多线程操作。而且 Go 语言多个线程间能共享相同的内存空间,但 js 每个线程都有自己独立的内存栈,通讯会比较麻烦。所以 go 有更高效的内存使用率,意味着更高的运行性能。
-
不类似于 webpack,esbuild 仅支持部分功能集合
- 支持 js、ts、jsx、css、json、文本、图片等资源
- 增量更新
- Sourcemap
- 开发服务器支持
- 代码压缩
- Code split
- Tree shaking
- 插件支持
并且明确声明未来也不会支持下列功能
- Elm, Svelte, Vue, Angular 等代码文件格式
- Ts 类型检查
- AST 相关操作 API
- Hot Module Replace(HMR)
- Module Federation
-
抛弃了一些功能外,它内部还定制了些功能
- 重写 ts 转译工具,完全抛弃 ts 类型检查,只做代码转换
- 大多数打包工具把词法分析、语法分析、符号声明等步骤拆解为多个高内聚低耦合的处理单元,各个模块职责分明,可读性、可维护性较高。而 Esbuild 则坚持性能第一原则,不惜采用反直觉的设计模式,将多个处理算法混合在一起降低编译过程数据流转所带来的性能损耗
- 一致的数据结构,以及衍生出的高效缓存策略
这种深度定制一方面降低了设计成本,能够保持编译链条的架构一致性;一方面能够贯彻性能第一的原则,确保每个环节以及环节之间交互性能的最优。虽然伴随着功能、可读性、可维护性层面的的牺牲,但在编译性能方面几乎做到了极致。
总的来说,esbuild 作为打包工具缺乏灵活性,并不能适用于各种复杂的应用场景,不能替代 webpack,不适合直接用在生产环境,但它从底层出发追求极致的性能这一点是很可取的,需要在它的基础上二次封装,兼顾工程化和性能,而 vite 正是巧妙的利用了这一点。
标签:浏览器,编译,webpack,Vite,vite,esbuild,打包 From: https://www.cnblogs.com/dirtycat/p/17508822.html