随着项目的日渐迭代,项目整体的代码量也会越来越多,从而导致项目体积越来越大;在Webpack时代,很多人会对历史项目(巨型项目)感到头疼,因为往往巨型项目在本地开发调试的时候会因为本地代码的修改触发HMR热更新重载页面,然而这一过程在Webpack的运行机制中显得很慢,并且是随着项目越大,热更新的速度也会越慢;

Webpack热更新慢的问题可以通过 babel-plugin-dynamic-import-node 插件来得到明显改善,或者通过手动实现动态按需加载(修改entry为当前项目中需要编译的部分或模块)亦可大幅提升热更新速度;

       热更新构建主要流程

在Webpack中,我们的每一次ctrl+s操作,都会触发热更新;此时热更新构建的一个过程应该是此时的终端显示Compiling......执行重新构建并打包,并生成新的hash值,启动Webpack-dev-server服务与浏览器通过WebSocket建立连接;此时的hash值会作为下一次编译生成的文件的前缀,以此类推;每次修改会触发重新编译,然后发出两次请求;

首先看json文件,发出请求返回的结果中有一个c参数和一个h参数,c代表的是本次热更新要对应的是c模块,h代表的是本次热更新重新编译的过程中新生成的hash值,将作为下一次热更新请求编译后生成的文件前缀使用;

js文件,是修改之后重新编译生成打包后的代码,重新对文件进行下载及网络资源加载;

Vite中热更新构建过程也是类似,Vite是在本地启动Vite Server服务,通过WebSocket与浏览器进行连接通信,并加入了WebSocket的定时心跳检测机制,拿到已修改更新的文件路径以及时间戳标识,然后再次带上这个时间戳作为参数去重新请求该文件修改后的版本,防止缓存;

 

       热更新边界

热更新边界即热更新边缘,定义了处于极值或者特殊情况的时候该如何去处理热更新;

正常来说我们Vue文件会正常热更新,因为Vue底层部分对热更新进行了自定义逻辑处理,重新定义了热更新的处理方式;但是当我们修改js文件或者ts文件,并且这个js或者ts文件刚好被.vue文件所引用,这个时候会怎么处理?

js或者ts文件修改之后,Vite会去对这个vue文件进行热更新,并重新加载该组件;此时,.vue文件就是热更新边界;

当js或者ts文件被修改之后,会沿着依赖树一直往上寻找依赖关系,直到查找到最近的一个可以热更新的模块,这个最近的一个热更新模块叫热更新边界;

但是又有一种特殊情况,比如我们修改main.ts或者main.js的时候,因为是入口文件,找不到最近的可以热更新的模块,这个时候Vite就不知道如何去执行热更新了,只能是通过刷新页面来解决;

       Vite热更新为什么比Webpack热更新快?

Webpack热更新运行机制:

Webpack会遍历你的应用程序中的所有文件,并启动一个开发服务器(Webpack-dev-server),然后将整个代码渲染到开发环境中。从entry入口文件开始,将其依赖的资源文件通过loader打包成一个文件夹,然后通过server传递到客户端运行;也正是因为这样的运行机制,也必将导致项目代码量增多,应用体积增大之后,Webpack热更新需要等待较久的时间才能反映到浏览器中;

Vite热更新运行机制:

Vite会在本地启动一个Vite Server服务,对于第三方依赖使用了速度更快的esbuild预构建,对于业务代码使用原生的ESM,访问这个服务,现代浏览器基本都已支持的import/export等语法可用来直接加载对应模块的服务端资源,绕过了构建打包过程,对请求的模块进行实时按需编译,热更新时仅需重新请求改动过的模块即可,绕过了Webpack热更新全局依赖与业务代码全部重新编译的过程;

       使用keep-alive组件导致热更新对ts文件失效,如何解决?

使用keep-alive组件实现页面级缓存,会导致热更新失效;个人理解是:因为vue框架底层源码部分对Vite热更新有特殊处理逻辑(import.meta.hot.accept Api用于传入一个回调函数,来定义该模块修改后,需要怎么去热更新,此Api一般提供给框架或者工具库的作者使用,业务代码中可不用关注),而ts文件是没有热更新逻辑的,所以会沿着依赖树一直往上寻找,往上找到一个可以热更新的模块对其进行热更新即可;keep-alive页面缓存和热更新概念冲突,在开发环境中我们可以判断舍弃掉keep-alive缓存,而在生产环境中我们可以舍弃热更新,达到解决问题的目的;

        解决方案:

 

     Vite劣势:

有好必有坏,Vite目前的机制是会大幅提高热更新的速度,解决Webpack机制中的巨型项目热更新等待过久的问题,提高开发效率;但是同时也正是因为Vite的运行机制,直接浏览器按需向服务端请求资源,这就造成了Vite项目的首屏加载没有Webpack快,因为Vite首屏的时候会发出大量的请求去拿到资源文件从而渲染页面,而Webpack不需要;同时懒加载性能方面,Vite也没有Webpack好;但是首屏渲染这个问题只是第一次加载的时候会比较慢,Vite对第三方依赖做了缓存处理,第二次之后的页面加载速度提升很多;总体来说,Vite是优大于劣;

 

Webpack与Vite热更新差异对比的更多相关文章

  1. webpack与browser-sync热更新原理深度讲解

    本文首发于CSDN网站,下面的版本又经过进一步的修订.原文:webpack与browser-sync热更新原理深度讲解本文包含如下内容: webpack-hot-middleware EventSou ...

  2. 图解 Webpack 4.x 热更新原理

    图解 Webpack 4.x 热更新原理 Webpack HMR ️ module.hot & module.hot.accept if (module.hot) { module.hot.a ...

  3. webpack+express实现“热更新”和“热加载”(webpack3.6以前的做法)

    “热更新”:对应的是 'webpack-dev-middleware' 中间件 “热加载”:对应的是 'webpack-hot-middleware' 中间件 为了使用这两个中间件,必须修改“webp ...

  4. unity热更新方案对比

    Unity应用的iOS热更新 •  什么是热更新 •  为何要热更新 •  怎样在iOS 上对Unity 应用进行热更新 •  支持Unity iOS 热更新的各种Lua 插件的对照 什么是热更新 • ...

  5. koa和egg项目webpack热更新实现

    背景 在用Node.js+Webpack构建的方式进行开发时, 我们希望能实现修改代码能实时刷新页面UI的效果. 这个特性webpack本身是支持的, 而且基于koa也有现成的koa-webpack- ...

  6. Webpack 多html入口、devServer、热更新配置

    一.clean-webpack-plugin: 在每次生成dist目录前,先删除本地的dist文件(每次自动删除太麻烦) 1.安装clean-webpack-plugin   npm/cnpm i c ...

  7. 优化单页面开发环境:webpack与react的运行时打包与热更新

    前面两篇文章介绍初步搭建单页面应用的开发环境: 第一篇:使用webpack.babel.react.antdesign配置单页面应用开发环境 第二篇:使用react-router实现单页面应用路由 这 ...

  8. Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(下篇——多页面VueSSR+热更新Server)

    Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(下篇--多页面VueSSR+热更新Server) @(HTML/JS) 这是Vue多页面框架系列文章的第二篇,上一篇(纯前 ...

  9. webpack的热更新

    webpack的热更新是如何做到的?说明其原理? webpack的热更新又称热替换(Hot Module Replacement),缩写为HMR. 这个机制可以做到不用刷新浏览器而将新变更的模块替换掉 ...

随机推荐

  1. java面试题(2022最新)

    1.String是基本数据类型么?不是基本数据类型,byte int char long flout duable boolem short 2.int 和integer区别int是基本数据类型,in ...

  2. 【干货】MySQL底层架构设计,你了解多少?

    很多开发同学对SQL优化如数家珍,却对MySQL架构一知半解.岂不是只见树叶,不见森林,终将陷入细节中不能自拔. 今天就一块学习MySQL分层架构,深入了解MySQL底层实现原理,以及每层的作用,我们 ...

  3. Acwing八数码

    此题用\(bfs\) 首先我们可以定义两个重要的数组 \(unordered\_map<string,int> d\)表示\(string\)距离\(start\)的交换次数 \(queu ...

  4. selenium环境配置和八大元素定位

    一.环境配置 1.selenium下载安装 安装一:pip install selenium(多数会超时安装失败) 安装二:pip install -i https://pypi.tuna.tsing ...

  5. NoSQL,关系型数据库,行列数据库对比、类比

    数据库对比.类比 关系型数据库.NoSQL 关系型数据库 表与表之间有关系.表存储一些格式化的数据结构,每个元组字段的组成都一样,这样便于表之间的联结操作.不过也限制了其性能瓶颈. 更支持SQL,支持 ...

  6. this关键字和构造方法

    构造方法: 构造方法的定义:构造方法是类的一个特殊成员,它会在类实例化对象的时候被自动调用 作用:可以在实例化对象的同时对这个对象的属性进行赋值 案例:Student student = new St ...

  7. scrollTop实例

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  8. Python3.7+jieba(结巴分词)配合Wordcloud2.js来构造网站标签云(关键词集合)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_138 其实很早以前就想搞一套完备的标签云架构了,迫于没有时间(其实就是懒),一直就没有弄出来完整的代码,说到底标签对于网站来说还是 ...

  9. Vue 路由的一些复杂配置

    1 # 一.路由的props参数 2 export default new VueRouter({ 3 routes:[ 4 { 5 name:'guanyu', // 命名路由 6 path:'/a ...

  10. MVCC多版本并发控制的理解

    前置知识 当前读与快照读 当前读 什么是当前读:读取的是最新的数据,不会读到老数据. 何时触发:update.insert.delete.select lock in share mode.selec ...