深入剖析vite到底是快还是慢原理详解

目录
  • 前言
  • Vite 的快
    • 快速的冷启动
    • 快速的热更新
  • Vite 的慢
    • 首屏性能
    • 懒加载性能
  • 结束语

前言

谈到 Vite,给人的第一印象就是 dev server 启动速度快。同样规模的项目,相比 Webpack 动辄十几秒甚至几十秒的的启动速度,Vite 简直是快到没朋友,往往数秒之内即可完成启动(PS: 都没有时间去喝一杯 ️ 啦)。

正好小编最近在做一些关于开发体验的性能优化,就想着把手上一些项目的开发模式更新为 Vite。经过一番操作,终于改造成功,而效果也不负众望,项目启动速度由原来的 25 s 如坐 一般跃升为 2 s,简直夸张。虽然也出现了一些诸如首屏、懒加载性能下降等负面效果,但整体来说依然利大于弊,开发幸福感提升非常明显。

接下来小编就通过本文给大家分析一下,具体聊一聊 Vite 的快和慢。

Vite 的快

Vite 的快,主要体现在两个方面: 快速的冷启动和快速的热更新。而 Vite 之所以能有如此优秀的表现,完全归功于 Vite 借助了浏览器对 ESM 规范的支持,采取了与 Webpack 完全不同的 unbundle 机制。

在本章节,小编将通过一个实际的项目,分别使用 WebpackVite 启动 dev server, 给大家展示一下 Vite 的威力。

快速的冷启动

由于是公司的内部项目,不方便将源代码上传到 github,所以小编只能通过 gif 动图的方式给大家展示 WebpackVite 启动 dev server 的过程。

Webpack

首先是通过 Webpack 启动 dev server,过程如下:

一个规模不是很大的项目,dev server 启动完成,居然花了 25 s 左右时间。如果项目持续迭代变得再大一点,那每次启动 dev server 就是一种折磨了。

这个问题,主要是由 Webpack 内部的核心机制 - bundle 模式引发的。

Webpack 能大行其道,归功于它划时代的采用了 bundle 机制。通过这种 bundle 机制,Webpack 可以将项目中各种类型的源文件转化供浏览器识别的 jscssimg 等文件,建立源文件之间的依赖关系,并将数量庞大的源文件合并为少量的几个输出文件。

bundle 工作机制的核心部分分为两块:构建模块依赖图 - module graph 和将 module graph 分解为最终供浏览器使用的几个输出文件。

构建 module graph 的过程可以简单归纳为:

获取配置文件中 entry 对应的 url (这个 url 一般为相对路径);

resolve - 将 url 解析为绝对路径,找到源文件在本地磁盘的位置,并构建一个 module 对象;

load - 读取源文件的内容;

transform - 使用对应的 loader 将源文件内容转化为浏览器可识别的类型;

parse - 将转化后的源文件内容解析为 AST 对象,分析 AST 对象,找到源文件中的静态依赖(import xxx from 'xxx') 和动态依赖(import('xx'))对应的 url, 并收集到 module 对象中;

遍历第 5 步收集到的静态依赖、动态依赖对应的 url,重复 2 - 6 步骤,直到项目中所有的源文件都遍历完成。

分解 module graph 的过程也可以简单归纳为:

预处理 module graph,对 module graphtree shaking

遍历 module graph,根据静态、动态依赖关系,将 module graph 分解为 initial chunkasync chunks

优化 initial chunkasync chunks 中重复的 module

根据 optimization.splitChunks 进行优化,分离第三方依赖、被多个 chunk 共享的 modulecommon chunks 中;

根据 chunk 类型,获取对应的 template

遍历每个 chunk 中收集的 module,结合 template,为每个 chunk 构建最后的输出内容;

将最后的构建内容输出到 output 指定位置;

Webpack 的这种 bundle 机制,奠定了现代静态打包器(如 RollupParcelEsbuild)的标准工作模式。

然而成也萧何败萧何,强大的 bundle 机制,也引发了构建速度缓慢的问题,而且项目规模越大,构建速度越是缓慢。其主要原因是构建 module graph 的过程中,涉及到大量的文件 IO、文件 transfrom、文件 parse 操作;以及分解 module graph 的过程中,需要遍历 module graph、文件 transform、文件 IO 等。这些操作,往往需要消耗大量的时间,导致构建速度变得缓慢。

开发模式下,dev server 需要 Webpack 完成整个工作链路才可以启动成功,这就导致构建过程耗时越久,dev server 启动越久。

为了加快构建速度,Webpack 也做了大量的优化,如 loader 的缓存功能、webpack5 的持久化缓存等,但这些都治标不治本,只要 Webpack 的核心工作机制不变,那 dev server 启动优化,依旧是一个任重道远的过程(基本上永远都达不到 Vite 那样的效果)。

Vite

同样的项目,这次换 Vite 启动。

通过 gif 动图,我们可以看到 dev server 的启动速度仅仅需要 2s 左右,相比 Webpack 如 爬行一样的速度,就如同坐 一般,开发幸福感顿时拉满。

Vite 之所以在 dev server 启动方面,如此给力,是因为它采取了与 Webpack 截然不同的 unbundle 机制。

unbundle 机制,顾名思义,不需要做 bundle 操作,即不需要构建、分解 module graph,源文件之间的依赖关系完全通过浏览器对 ESM 规范的支持来解析。这就使得 dev server 在启动过程中只需做一些初始化的工作,剩下的完全由浏览器支持。这和 Webpackbundle 机制一比,简直就是降维打击,都有点欺负人了 。

那有的同学就会问,源文件的 resolveloadtransformparse 什么时候做呢 ?

答案是浏览器发起请求以后,dev server 端会通过 middlewares 对请求做拦截,然后对源文件做 resolveloadtransformparse 操作,然后再将转换以后的内容发送给浏览器。

这样,通过 unbundle 机制, Vite 便可以在 dev server 启动方面获取远超于 Webpack 的优秀体验。

最后再总结一下, unbundle 机制的核心:

  • 模块之间的依赖关系的解析由浏览器实现;
  • 文件的转换由 dev servermiddlewares 实现并做缓存;
  • 不对源文件做合并捆绑操作;

快速的热更新

除了 dev server 启动外, Vite 在热更新方面也有非常优秀的表现。

我们还是通过同一个项目,对 WebpackVite 的热更新做一下比较。

Webpack

首先是 Webpack 在热更新方面的表现。

观察 gif 动图,修改源文件以后,Webpack 发生耗时大概 5 s 的重新编译打包过程。

dev server 启动以后,会 watch 源文件的变化。当源文件发生变化后,Webpack 会重新编译打包。这个时候,由于我们只修改了一个文件,因此只需要对这个源文件做 resolveloadtransfromparse 操作,依赖的文件直接使用缓存,因此 dev server 的响应速度比冷启动要好很多。

dev server 重新编译打包以后,会通过 ws 连接通知浏览器去获取新的打包文件,然后对页面做局部更新。

Vite

再来看看 Vite 在热更新方面的表现。

观察 gif 动图,可以发现 Vite 在热更新方面也是碾压 Webpack

由于 Vite 采用 unbundle 机制,所以 dev server 在监听到文件发生变化以后,只需要通过 ws 连接通知浏览器去重新加载变化的文件,剩下的工作就交给浏览器去做了。(忍不住要给 Vite 点个

(0)

相关推荐

  • Vite vue3多页面入口打包以及部署踩坑实战

    目录 为什么需要多入口? 一.改造项目 二.vite.config.ts配置 三.部署 总结 为什么需要多入口? 公司原生的移动端上需要用webview引入一些性能要求不高的H5页面,初步考虑后选择用vue试个水,前期页面跳转选择使用vue-router,测试过程中在安卓高版本下右滑返回效果尚可,ios端初步尝试使用的最左侧touch事件移动距离检测以及router判断index添加过场动画,但是整体的效果依然达不到下图的效果. 原先项目中是使用多个html页面以及原生自带的协议去打开html,

  • 使用Vite处理css less及postcss示例详解

    目录 1. css 2. less 3. postcss 4. 小结 1. css 当前,我们的 vite的基本使用 项目中是没有 css 代码的,但在真实的项目中,肯定会有 css 代码,那 Vite 能否帮助我们对 css 做支持呢?我们可以测试一下,在 src 目录下新建 css 文件夹,在 css 文件夹中新建 style.css 文件,内容如下: body { background-color: #f66; } 有了这个 css 文件后,先来思考一下,这个 css 文件现在有被打包吗?

  • 如何用Vite构建工具快速创建Vue项目

    目录 和Webpack相比,Vite具有以下特点 Vite构建Vue项目 构建过程可能会发生的一些问题 总结 和Webpack相比,Vite具有以下特点 1.快速的冷启动,不需要等待打包 2.即时的热模块更新,真正的按需编译,不用等待整个项目编译完成 Vite构建Vue项目 前提:安装Node.js和Vite 第一步通过npm创建Vite项目 npm init vite-app 项目名称 # 例如 npm init vite-app HelloVue 第二步当项目创建成功后,cd到项目目录 cd

  • vue使用vite配置跨域以及环境配置详解

    目录 如何配置跨域,代理域名 区分开发环境和生产环境,以及预发布环境 可以做什么事 补充:解决跨域常用方法 一.VUE中常用proxy来解决跨域问题 二.JSONP解决跨域 三.CORS是跨域资源共享(Cross-Origin Resource Sharing),以 ajax 跨域请求资源,支持现代浏览器,IE支持10以上 四.iframe实现跨域 总结 如何配置跨域,代理域名 不管使用什么脚手架,配置代理都是绕不开的话题,下面是vite的代理 server: { proxy: { '/api'

  • vite的搭建与使用的详细步骤

    目录 1.安装: 2.在vite项目中使用TypeScript 3.vite项目使用less sass scss 4.vite打包 5.下面就来创建一个标准的项目 实际开发中编写的代码往往是不能被浏览器直接识别的,比如ES6,TypeScript,Vue文件等.所以此时我们必须通过构建工具来对代码进行转换,编译,类似的工具有webpack,rollup,parcel.但是随着项目越来越大,需要处理的javascript呈指数级增长,模块越来越多.构建工具需要很长时间才能开启服务器,HMR也需要几

  • Vite多环境配置项目高定制化能力详解

    目录 业务背景 多环境场景的业务形态 Vite多环境方案实现 多模式文件配置 自定义环境变量 Vite默认环境变量 通过插件透传环境变量 客户端环境差异定制 效果图 解决的业务场景思考 业务背景 近些年来,随着前端工程架构发展,使得前端项目中也能拥有如后端工程的模块能力.正所谓 “能力(越)越大(来),责任(越)越大(卷)”,现在的前端工程不仅仅要满足业务需求,还伴随更多复杂的环境适配问题,例如: api请求的域名会根据不同环境而不同: 线上环境和测试环境在打包策略有所不同「如线上要隔离sour

  • 如何使用vite搭建vue3项目详解

    目录 一:npm构建 二:更改http://localhost:3000/到8080与Network路由访问 三:配置vite别名(npm install @types/node --save-dev) 四 :路由(npm install vue-router@4) 五:vuex(npm install vuex@next --save) 六:Eslint(可选)(npm install --save-dev eslint eslint-plugin-vue) 七:less/sass(可选)(n

  • 深入剖析vite到底是快还是慢原理详解

    目录 前言 Vite 的快 快速的冷启动 快速的热更新 Vite 的慢 首屏性能 懒加载性能 结束语 前言 谈到 Vite,给人的第一印象就是 dev server 启动速度快.同样规模的项目,相比 Webpack 动辄十几秒甚至几十秒的的启动速度,Vite 简直是快到没朋友,往往数秒之内即可完成启动(PS: 都没有时间去喝一杯 ️ 啦). 正好小编最近在做一些关于开发体验的性能优化,就想着把手上一些项目的开发模式更新为 Vite.经过一番操作,终于改造成功,而效果也不负众望,项目启动速度由原来

  • video.js 实现视频只能后退不能快进的思路详解

    主要思路是点击进度条需要获取拖动前的时间点,我用mouseup事件去处理的,获得到了oldTime 就好办,然后根据需求限制拖动快进快退,因为项目允许回看,不允许快进,所以得记录maxTime,记录用户正常情况观看视频最大的那个时间点,不允许超过maxTime var isMousedown = false; var oldTime=0,newTime=0,maxTime=0; //拖动进度条会先执行这个事件 $(".vjs-progress-holder").mouseup(func

  • Python实现超快窗口截图功能详解

    实现思路是先获取到当前最上面活动的窗口信息,然后提取该窗口的名称信息. 之后获取窗口的坐标信息,即左上角的开始坐标及右下角的结束坐标.最后直接截图并将截图的图片进行展示. 其中用到了两个第三方模块,分别是win32gui和Pillow,安装命令如下: pip install Pillow pip install win32gui 将其中使用到的三个非标准库导入进来. from win32gui import * # 操作windows窗口 from PIL import ImageGrab #

  • Vue3中Vite和Vue-cli的特点与区别详解

    目录 1. 创建3.0项目 Vite 与 Vue-cli 是什么? Vue-cli 的特点: Vite 的特点: Vite 和 Vue-cli的区别: 总结: 1. 创建3.0项目 vue-cli : 安装并执行 npm init vue@latest 选择项目功能时: 除了第一项的项目名字外,其他可以暂时No cd title npm install npm run dev :运行 npm run build: 打包 (生成一个dist文件夹) vite: 使用vite 体验更快速 npm i

  • JS小游戏之极速快跑源码详解

    本文实例讲述了JS小游戏的极速快跑源码,分享给大家供大家参考.具体如下: 游戏运行后如下图所示: Javascript部分代码如下: /** 极速快跑 * Author: fdipzone * Date: 2012-07-15 * Ver: 1.0 */ var gameimg = ['images/start.png', 'images/start_over.png', 'images/go.png', 'images/go_over.png', 'images/running.gif', '

  • django最快程序开发流程详解

    1.建立工程 在工程目录下打开cmd,输入以下命令.其中mysite是项目名称. django-admin startproject mysite 命令运行完后,在该目录下会出现一个名为mysite的文件夹.下面是工程的目录结构 2.创建一个新的应用(app) cmd进入mysite目录(有manage.py那个文件夹),运行以下命令.其中helloapp是应用名 python manage.py startapp helloapp 然后会在manage.py同级目录下生成一个helloapp的

  • C++STL函数和排序算法的快排以及归并排序详解

    目录 一.队列是什么? 二.排序算法 1.快速排序 2.归并排序 总结 一.队列是什么? 头文件queue主要包括循环队列queue和优先队列priority_queue两个容器. 像栈一样,队列(queue)也是一种线性表,它的特性是先进先出,插入在一端,删除在另一端.就像排队一样,刚来的人入队(push)要排在队尾(rear),每次出队(pop)的都是队首(front)的人. 就像管道一样先进先出. 队列的相关概念: 1.队头与队尾: 允许元素插入的一端称为队尾,允许元素删除的一端称为队头.

  • 详解antd+react项目迁移vite的解决方案

    antd+react+webpack往往是以react技术栈为主的前端项目的标准组合,三者都有成熟的生态和稳定的表现,但随着前端圈的技术不断革新,号称下一代构建平台vite2的发布,webpack似乎不那么香了,为什么这么说呢,因为vite太快了.经过一段时间的尝试,决定在项目中把webpack替换成vite试试,遂写成本文分享给大家. Vite是什么 作为本文的主角,首先简单介绍一下vite这个构建工具,该工具是尤雨溪推出的[下一代前端开发和构建工具],vite其实也不是一个新的工具,早在一年

随机推荐