vite
介绍
adv. 急速地;轻快地 /viːt/
vite:就是借助浏览器原生 ES Modules 能力,当浏览器发出请求时,为浏览器按需提供 ES Module 文件,浏览器获取 ES Module 文件会直接执行,即使首次启动的预构建也是使用速度惊人的esbuild完成,但是要优化的点:首屏、懒加载性能
webpack:需要构建完整的依赖关系,打包成一个bundle.js
prod环境打包区别
vite在生产环境的构建目前用的Rollup
- vite在生产环境,如果使用ESM会存在大量额外网络请求问题:
尽管原生ESM现在得到了广泛支持,但由于嵌套导入会导致额外的网络往返,在生产环境中发布未打包的ESM仍然效率低下;
最好的方式还是代码进行 tree-shaking、懒加载、和 chunk 分隔等;
- 使用 rollup打包而不是速度惊人的esbuild,这是因为esbuild针对构建应用的重要功能仍然还在持续开发中 —— 特别是代码分割和css处理方面,rollup在应用打包方面更加的成熟
首屏、懒加载性能优化
webpack bundle得到了一个完整的模块关系依赖包;vite由于unbundle机制,首屏、懒加载会存在一定的问题,处理时需要额外做以下工作:
- 由于未对源文件做合并捆绑操作,导致大量的http请求;
- 动态加载的文件需要对源文件进行转换操作:resolve、load、transform、parse;
- 预构建、二次预构建操作也会阻塞首屏请求,直到预构建完成为止;
- 但是由于缓存的存在,当第一次加载完成(预构建)之后,再次reload的时候性能会有较大的提升;
服务启动速度
webpack需要先把所有的模块建立依赖关系打包成一个大文件,速度相对较慢;
vite将应用中的模块区分为 依赖(node_modules) 和 源码(项目代码) 两类,进行预构建,速度会快很多;
依赖:使用esbuild预构建,esbuild使用Go编写,比以Node.js编写的打包器预构建依赖快10-100倍;
初次预构建完成后,会在node_modules中生成 .vite文件,后期不需要再次进行依赖的预构建;
源码:在浏览器请求时按需转换并以原生ESM方式提供源码,让浏览器接管了打包程序的部分工作;
由于是按需提供,所以在首屏、懒加载方面相比于webpack会存在一定的差异;
热更新速度
webpack
编辑文件后将重新构建文件本身;所以webpack支持了动态模块热重载HMR(Hot Module Replacing),这较大的提升了开发体验
vite
在vite中,HMR是在原生ESM上执行的,当编辑一个文件时,只需要精确地使已编辑的模块与其最近的 HMR边界之间的链失效(大多数时候只需要模块本身),使HMR更新始终快速,无论应用的大小;
vite同时利用HTTP头来加速整个页面的重新加载(再次让浏览器为我们做更多事情):
源码模块的请求会根据304 Not Modified进行协商缓存;
依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable进行强缓存;