随着项目的日渐迭代,项目整体的代码量也会越来越多,从而导致项目体积越来越大;在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. 看起来是线程池的BUG,但是我认为是源码设计不合理。

    你好呀,我是歪歪. 前几天看到一个 JDK 线程池的 BUG,我去了解了一下,摸清楚了它的症结所在之后,我觉得这个 BUG 是属于一种线程池方法设计不合理的地方,而且官方在知道这个 BUG 之后表示: ...

  2. 下载Chrome离线安装包

    https://www.google.com/chrome/thankyou.html?standalone=1&platform=mac&installdataindex=defau ...

  3. 千万小心,99%的Java程序员会踩这些坑

    前言 作为Java程序员的你,不知道有没有踩过一些基础知识的坑. 有时候,某个bug查了半天,最后发现竟然是一个低级错误. 有时候,某些代码,这一批数据功能正常,但换了一批数据就出现异常了. 有时候, ...

  4. EfficientFormer:轻量化ViT Backbone

    论文:<EfficientFormer: Vision Transformers at MobileNet Speed > Vision Transformers (ViT) 在计算机视觉 ...

  5. Centos7中配置NIS:用户账号管理

    NIS:网络信息服务 Linux系统中用户按地域分两类:本地用户,远程用户(NIS.LDAP.AD)模式:C/S模式 ypbind是定义NIS服务器的客户端进程,一旦确定了服务器位置,客户端绑定到了服 ...

  6. Linux系统下安装windows字体笔记

    源文档地址:https://www.e-iceblue.cn/spiredocforjavaconversion/word-to-pdf-font-issue.html windows字体路径:C:\ ...

  7. 【Github开源项目体验】- ZFile 基于 Java 的在线网盘

    [Github开源项目体验]- ZFile 基于 Java 的在线网盘 在线云盘.网盘.OneDrive.云存储.私有云.对象存储.h5ai.上传.下载 date: 2022-08-02 addres ...

  8. 6.22 NOI 模拟

    \(T1\)递归 给出 \(Thue-Morse\) 序列的定义三 每次 \(0\rightarrow 01\),\(1\rightarrow 10\) \(0\rightarrow 01 \righ ...

  9. Dapr学习(4)之eShopOnDapr部署(Rancher2.63&k3s)

    本篇主要讲述一下github上基于Dapr实现的商城demo在(K8s or K3s)环境中的部署实践,本文环境基于k3s&rancher2.6.3 1.eShopOnDapr源代码及概述 源 ...

  10. 主流前沿的开源监控和报警系统Prometheus+Grafana入门之旅

    Prometheus概述 定义 Prometheus 官网地址 https://prometheus.io/ Prometheus 官网文档地址 https://prometheus.io/docs/ ...