【Webpack 性能优化系列(1) - HMR 热模块替换】

article/2025/10/7 11:55:18

webpack系列文章:

  • 【Webpack 性能优化系列(9) - 多进程打包】极大的提升项目打包构建速度!!!
  • 【Webpack 性能优化系列(8) - PWA】使用渐进式网络应用程序为我们的项目添加离线体验
  • 【Webpack 性能优化系列(7) - 懒加载和预加载】
  • 【Webpack 性能优化系列(6) - code splitting 】通过代码分割来获取更小的 bundle,优化资源加载
  • 【Webpack 性能优化系列(5) - tree shaking 】去除未引用代码,减少代码体积!!!
  • 【Webpack 性能优化系列(4) - 缓存 】详解如何做bable缓存和文件资源缓存
  • 【Webpack 性能优化系列(3) - oneOf】
  • 【Webpack 性能优化系列(2) - source-map】
  • 【Webpack 生产环境配置】近两万字长文总结学习如何提取css为单独文件、css的压缩和兼容性处理,如何压缩html和js、如何做js语法检查eslint和js兼容性处理babel!!!
  • 【Webpack 开发环境配置】万字长文总结学习如何打包样式资源、html资源、图片资源和其他资源?devServer是什么,如何配置?
  • 【Webpack 简介及五个核心概念】

webpack性能优化

webpack性能优化主要指两个环境:

  • 开发环境性能优化
  • 生产环境性能优化

除了前面的开发环境和生产环境配置,还有以下性能优化处理:

开发环境性能优化包括:

  • 优化打包构建速度
    • HMR
  • 优化代码调试
    • source-map

生产环境性能优化包括:

  • 优化打包构建速度
    • oneOf
    • babel缓存
    • 多进程打包
    • externals
    • dll
  • 优化代码运行的性能
    • 缓存(hash-chunkhash-contenthash)
    • tree shaking
    • code split
    • 懒加载/预加载
    • pwa

HMR 热模块替换

为什么要使用HMR 热模块替换功能?

我们回看一下前面总结的开发环境配置:

/*开发环境配置:能让代码运行运行项目指令:webpack 打包运行项目npx webpack-dev-server 启动webpack-dev-server
*/const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {entry: './src/js/index.js',output: {filename: 'js/built.js',path: resolve(__dirname, 'build')},module: {rules: [// loader的配置{// 处理less资源test: /\.less$/,use: ['style-loader', 'css-loader', 'less-loader']},{// 处理css资源test: /\.css$/,use: ['style-loader', 'css-loader']},{// 处理图片资源test: /\.(jpg|png|gif)$/,loader: 'url-loader',options: {limit: 8 * 1024,name: '[hash:10].[ext]',// 关闭es6模块化esModule: false,outputPath: 'imgs'}},{// 处理html中img资源test: /\.html$/,loader: 'html-loader'},{// 处理其他资源exclude: /\.(html|js|css|less|jpg|png|gif)/,loader: 'file-loader',options: {name: '[hash:10].[ext]',outputPath: 'media'}}]},plugins: [// plugins的配置new HtmlWebpackPlugin({template: './src/index.html'})],mode: 'development',devServer: {contentBase: resolve(__dirname, 'build'),compress: true,port: 3000,open: true}
};

下面我们看一下这种配置存在什么问题

运行指令:npx webpack-dev-server ,启动webpack-dev-server

然后在index.js文件中打印一段话:console.log('index.js文件被加载了~');
在这里插入图片描述
只要index.js文件重新被加载,就会打印上面那段话

现在去修改样式文件
在这里插入图片描述

#box {width: 400px;// 200px修改为400pxheight: 200px;background-image: url('../imgs/angular.jpg');background-repeat: no-repeat;background-size: 100% 100%;
}

修改之后,很明显整体页面被刷新,内容被重新打印了一次
在这里插入图片描述
意思就是:当我们修改css文件时,明明js文件没有变化,但js文件也被重新加载了一次,所以打包的时候,看似只修改了css文件,实际上是把js文件也重新打包了一次,这是一个问题。

再写一个模块:
在这里插入图片描述
在index.js中引入上面那个print模块,并且在下面调用一下:
在这里插入图片描述
效果:
在这里插入图片描述
发现模块被加载,并且模块的print方法被调用执行了

现在我们修改一下print.js文件,'hello print'改为`‘hello webpack’

console.log('print.js被加载了~');function print() {const content = 'hello webpack';console.log(content);
}export default print;

保存查看效果,可以发现整个页面被重新刷新了,所有代码重新执行:
在这里插入图片描述
这个意思就代表:假设以后我们有100个js模块,100个样式模块,如果只修改其中某一个模块,这整200个模块就需要重新打包,这个速度可以想想是非常慢的,更不要说以后的模块会越来越多,那打包情况只会越来越慢。

所以我们想实现这样的功能:如果只有一个模块发生变化,那么只需要修改这一个模块代码就足够了,其他模块理应是不变的

做这个功能要使用webpack的HMR 热模块替换

HMR: hot module replacement 热模块替换 / 模块热替换

作用:一个模块发生变化,只会重新打包这一个模块(而不是打包所有模块),极大提升构建速度

HMR功能的使用非常简单,只需要在devServer里配置hot:true即可:

  devServer: {contentBase: resolve(__dirname, 'build'),compress: true,port: 3000,open: true,// 开启HMR功能// 当修改了webpack配置,新配置要想生效,必须重新webpack服务hot: true}

修改配置后,运行指令:npx webpack-dev-server ,重新启动webpack-dev-server

开启HMR功能跟之前更新有什么区别?

首先打印结果这里已经显示HMR功能已经开启:
在这里插入图片描述
下面修改样式文件,保存,可以发现只更新一个样式文件,js文件并不会重新加载:
在这里插入图片描述
可以发现:样式文件可以使用HMR功能,之所以能使用是因为style-loader内部实现了~

这也是为什么我们在开发环境要使用style-loader,生产环境要用MiniCssExtractPlugin.loader提取成单独文件,因为开发环境借助style-loader能让性能更好,打包速度更快,但是上线的时候考虑性能优化,所以不能用

前面样式文件可以使用HMR功能,js文件行不行呢?

修改print.js文件,保存,发现整个页面被重新刷新了一遍,这一点可以知道js文件默认不能使用HMR功能

html文件可以使用HMR功能吗?

在html文件中修改一段代码:
在这里插入图片描述
保存后发现当开启HMR功能后,html文件改动后并没有任何变化:
在这里插入图片描述
html文件: 默认不能使用HMR功能,同时会导致问题:html文件不能热更新了~

通过修改entey入口,改成一个数组,把html文件引入就可以解决上面的问题了:

entry: ['./src/js/index.js', './src/index.html'],

修改配置后,打包运行项目
在这里插入图片描述
测试发现html文件也是没有HMR功能的,一旦html文件发生变化,整体页面就会重新刷新

那么html文件需要HMR功能吗?

html不像js文件,一个项目里会有很多个js模块,而运行的html只会有一个,一旦发生变化,就一定要变化,它只需要变化一个文件,既然一定要变化,那就没办法优化,所以html文件不用做HMR功能

前面讲到了js默认不能使用HMR功能,这并不代表js就不需要HMR功能,如何对js文件使用HMR功能?

用法:

if (module.hot) {// 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效module.hot.accept('./print.js', function() {// 方法会监听 print.js 文件的变化,一旦发生变化,其他模块不会重新打包构建。// 会执行后面的回调函数print();});
}

在这里插入图片描述
修改print.js,查看效果
在这里插入图片描述
可以发现,print.js会重新更新,但index.js不会变,即index.js不会重新加载,样式和结构也不会重新加载,这就是js文件的HMR功能的使用

注意:HMR功能对js的处理,只能处理非入口js文件的其他文件。

为什么呢?

因为入口文件会将其他文件全部引入,一旦入口文件变化,其他文件重新引入,就会重新加载,这是没办法阻止的,所以入口文件是做不了HMR功能的,只能对入口文件引入的一些依赖或者其他文件做HMR功能。

比如修改入口文件下面的打印代码:
在这里插入图片描述
保存,可以发现所有东西都要重新打包构建:
在这里插入图片描述

参考

  • https://www.bilibili.com/video/BV1e7411j7T5?p=17&spm_id_from=pageDriver

http://chatgpt.dhexx.cn/article/kH40etAf.shtml

相关文章

hmr webpack 不编译_Webpack HMR 热更新实现原理深入分析

概述 在使用 Webpack 构建开发期时,Webpack 提供热更新功能为开发带来良好的体验和开发效率,那热更新机制是怎么实现的呢? 代码实现 Webpack 配置添加 HotModuleReplacementPlugin 插件 new webpack.HotModuleReplacementPlugin({ // Options…

webpack4.0核心概念(十)—— HMR(热模块替换-局部刷新)

HMR:当修改一个js或者css的时候,只刷新修改的内容,不进行整个页面的刷新。 css的HMR——只支持开发环境 不能使用mini-css-extract-plugin需要使用style-loader,因为它不支持抽离出的css,需要用style-loader ① 在webpack.config.js中配置 …

前端工程化——Livereload和HMR、本地开发服务器

目录 本地开发服务器解决的问题 动态构建 Mock服务 动态构建 源码改动之后,浏览器应该在何时获取重新编译后的资源? Livereload和HMR 有了构建系统的支持,前端开发人员可以使用诸多有利于开发和维护的技术进行源代码编写。然而如果在开…

hmr webpack 不编译_webpack hmr

参考: hmr技术支持程序运行时的模块(amd、commonJS等)的修改、添加和删除,而不用整个程序重新加载,这可以提升开发的效率: hmr后程序的状态可以得到保存 仅仅改变变化的部分,其余不变 调样式更加快捷,基本比…

18.webpack4之HMR

1.HMR(Hot Module Replacement)热模块替换 在开发环境,可以使用热模块替换(HMR)去实现如果一个模块发生变化,只会重新打包这一个模块(而不是所有模块都进行打包),而无需重…

webpack5之HMR原理探究

一、概念介绍 模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新所有类型的模块,而无需完全刷新。 主要是通过以下几种方式,来显著加快开发速度: 保留在完全重新加载页面期间丢失的应用程…

hmr webpack 不编译_一文搞懂 webpack HMR 原理

关注「前端向后」微信公众号,你将收获一系列「用心原创」的高质量技术文章,主题包括但不限于前端、Node.js以及服务端技术 一.HMR Hot Module Replacement(HMR)特性最早由 webpack 提供,能够对运行时的 JavaScript 模块进行热更新(无需重刷&a…

Webpack HMR 原理全解析

执行 npx webpack serve 命令后,WDS 调用 HotModuleReplacementPlugin 插件向应用的主 Chunk 注入一系列 HMR Runtime,包括: 用于建立 WebSocket 连接,处理 hash 等消息的运行时代码 用于加载热更新资源的 RuntimeGlobals.hmrDow…

vite1.x 热更新(HMR)的实现原理

前言 将近一年前自己尝试阅读vite源码(2.x),虽然也有些收获但整体并没有到达我的预期,对于vite也是停留在一知半解的程度上。最近想重新开始学习vite,但回顾之前的学习历程,感觉不太想继续之前的方式&…

Webpack HMR 原理解析

Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换老的模…

Webpack的HMR原理解析

Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换老的模…

Esbuild Bundler HMR

Esbuild 虽然 bundler 非常快,但是其没有提供 HMR 的能力,在开发过程中只能采用 live-reload 的方案,一有代码改动,页面就需要全量 reload ,这极大降低开发体验。为此添加 HMR 功能至关重要。 经过调研,社…

Vite HMR

传统webpack的hmr是使用webpack的HotModuleReplacementPlugin,而vite则是采用native ES Module的devServer。 初始化本地服务器加载并运行对应的plugin 最重要的一件事就是运行plugin,目前vite支持的plugin大体如下图所示 1、建立ViteDevServer服务器…

webpack HMR

HMR或者hot模式下,启动webpack会在浏览器与服务器之间会建立一个websocket连接,使得浏览器可以和服务端建立全双工通信;当应用程序的代码更新时,会要求HMR runtime检查更新,有更新时,在websoket连接中会返回…

webpack中的HMR(热更新)原理剖析

简介 Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换…

HMR(热替换)

HMR 即模块热替换(hot module replacement)的简称,它可以在应用运行的时候,不需要刷新页面,就可以直接替换、增删模块。webpack 可以通过配置 webpack.HotModuleReplacementPlugin 插件来开启全局的 HMR 能力&#xff…

面试官:说说Webpack的热更新是如何做到的?原理是什么?

一、是什么 HMR全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用 例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整…

Webpack 热更新HMR 原理全解析

一、什么是 HMR HMR 全称 Hot Module Replacement,中文语境通常翻译为模块热更新,它能够在保持页面状态的情况下动态替换资源模块,提供丝滑顺畅的 Web 页面开发体验。 HMR 最初由 Webpack 设计实现,至今已几乎成为现代工程化工具…

curl.perform() pycurl.error: (23, 'Failed writing body (0 != 59)')

在使用python3.7编码时,引入pycurl模块和StringIO模块后,容易引起上述错误 导入StringIO模块的解决方案: 只有在python2中才能导入StringIO模块,直接 from StringIO import StringIO 即可 但是python3,STringIO和…

关于python的url处理

基本环境: python2.7 1 完整的url语法格式: 协议://用户名密码:子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数值#标识 2 urlparse模块对url的处理方法 urlparse模块对url的主要处理方法有:urljoin/urlsplit/urlunsplit/urlpar…