Webpack5 常用优化总结
本文主要总结经常用到的一些代码性能优化、减小代码体积、提升webpack打包构建速度等内容的方法。具体的实现可参考webpack官网查看相关示例。
注:如果读者还未接触过webpack,请先了解webpack的基本使用。
正文:
SourceMap ---- 提升开发体验
SourceMap源代码映射,是一个用来生成源代码与构建后代码一一映射的文件的方案。
使用webpack打包之后会生成一个与打包文件对应的.map
文件,里面包含源代码和构建后代码每一行、每一列的映射关系。当构建后的代码报错时,其会通过.map
文件将构建后代码中出错的位置映射到源代码出错的位置,从而让浏览器的报错提示的是源代码文件报错的位置信息,帮助开发人员快速定位。
解决方案: 可以通过设置devtool来控制如何生成source map。开发模式下我们一般使用cheap-module-source-map
,优点:打包编译速度快,只包含行映射,缺点:没有列映射。生产模式下使用source-map
,优点:包含行和列的映射,缺点:打包编译速度慢。
// webpack.dev.js
module.exports = {mode: 'development',devtool: 'cheap-module-source-map'
}
// webpack.prod.js
module.exports = {mode: 'production',devtool: 'source-map'
}
提升构建打包速度
1. HotModuleReplacement(HMR)模块热替换
在webpack5中,热更新是webpack默认开启的。开发时只重新编译打包更新变化了的代码,不变的代码使用缓存,从而实现局部更新,而不是刷新整个页面。
// webpack.config.js
module.exports = {devServer: {hot: true}
}
2. OneOf 规则数组 只使用第一个匹配规则
当在webpack配置文件中写了很多处理不同资源文件的loader
时,资源文件会遍历所有loader
进行解析处理,当使用了oneOf
规则之后,资源文件一旦被某个loader
处理了,就不会继续往下遍历,从而使打包速度更快。
// webpack.config.js
module.exports = {module: {rules: [{oneOf: [{test: /\.css$/,use: ['style-loader', 'css-loader']},{test: /\.less$/,use: ['style-loader', 'css-loader', 'less-loader']},{test: /\.s[sc]ss$/,use: ['style-loader', 'css-loader', 'sass-loader']},{test: /\.styl$/,use: ['style-loader', 'css-loader', 'stylus-loader']},{test: /\.(png|jpe?g|gif|webp|svg)$/,type: 'asset',parser: {dataUrlCondition: {// 小于10KB的图片转base64maxSize: 10 * 1024}},generator: {filename: 'static/img/[hash:10][ext][query]'}},{test: /\.(ttf|woff2?|mp3|mp4|avi)$/,type: 'asset/resource',generator: {filename: 'static/media/[hash:10][ext][query]'}},{test: /.\.js$/,exclude: /node_modules/,loader: 'babel-loader'}]}]}
}
3. Include/Exclude
引入或排除某些文件,处理的文件更少,速度更快。例如开发时我们用到了第三方的库或者插件,那么这些文件是不需要编译就可以使用的,所以可以排除(exclude)对这些文件的处理。或者只处理(include)某个文件夹下面的源代码。二者选其一使用。
// webpack.config.js
const path = require('path')
const ESlintPlugin= require('eslint-webpack-plugin')module.exports = {module: {rules: [{test: /.\.js$/,// 排除node_modules下的文件 不作处理exclude: /node_modules/,loader: 'babel-loader'},// 或者{test: /.\.js$/,// 只处理src下的内容 其他文件不处理include: path.resolve(__dirname, './src'),loader: 'babel-loader'},]},plugins: [new ESlintPlugin([context: path.resolve(__dirname, './src'),exclude: /node_modules/, // 默认值//或者include: path.resolve(__dirname, './src'),])]
}
4. Cache 缓存
可以对eslint和babel处理的结果进行缓存,让后续打包速度更快。
// webpack.config.js
const path = require('path')
const ESlintPlugin= require('eslint-webpack-plugin')module.exports = {module: {rules: [{test: /.\.js$/,// 排除node_modules下的文件 不作处理exclude: /node_modules/,loader: 'babel-loader',options: {cacheDirectory: true, // 开启babel缓存cacheCompression: false // 关闭缓存文件压缩 }},]},plugins: [new ESlintPlugin([context: path.resolve(__dirname, './src'),exclude: /node_modules/, // 默认值cache: true, // 开启缓存cacheLocation: path.resolve(__dirname, './node_modules/.cache/eslintcache') // 定义缓存位置])]
}
5. Thead 多进程打包
当项目非常庞大的时候,打包速度越来越慢,主要是对js文件进行检查(eslint)、编译(babel)、压缩(terser),要提升运行速度可以开启多进程同时处理js文件。由于进程启动通信都是有开销的,所以只有在代码比较多的时候处理才有效果。
npm i thread-loader --save-dev
使用时,需将此 loader 放置在其他 loader 之前。放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行。
在 worker 池中运行的 loader 是受到限制的。例如:
- 这些 loader 不能生成新的文件。
- 这些 loader 不能使用自定义的 loader API(也就是说,不能通过插件来自定义)。
- 这些 loader 无法获取 webpack 的配置。
每个 worker 都是一个独立的 node.js 进程,其开销大约为 600ms 左右。同时会限制跨进程的数据交换。
请仅在耗时的操作中使用此 loader!
// webpack.config.js
const os = require('os')
const ESlintPlugin= require('eslint-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin') // 内置插件const threads = os.cups().length // 获取CPU核数module.exports = {module: {rules: [{test: /\.js$/,include: path.resolve('src'),use: [{loader: "thread-loader",options: {works: threads }},{loader: "babel-loader" }],},],},plugins: [new ESlintPlugin([context: path.resolve(__dirname, './src'),exclude: /node_modules/, // 默认值cache: true, // 开启缓存cacheLocation: path.resolve(__dirname, './node_modules/.cache/eslintcache'), // 定义缓存位置threads, // 开启多进程和设置数量]),new TerserPlugin({ // 代码压缩parallel: threads //开启多进程和设置数量})],// 压缩插件 第二种写法optimization: {minimizer: [new CssMinimizerPlugin(), // css文件压缩new TerserPlugin({ // js代码压缩parallel: threads //开启多进程和设置数量})]}
};
减小代码体积
1. Tree Shaking
当我们编写了很多工具函数或者引入了第三方库,可能在实际开发中只应用了其中一部分,那么在打包时这些未用到的代码就无须进行打包。Tree Shaking就帮我们做了这件事情。它可以移除JS上下文中的死代码,且其语法依赖于ESM,不支持CommonJS。
在Webpack中已经默认开启了此配置,所以开发者无需再进行配置。
2. @babel/plugin-transform-runtime
此插件可以对babel进行处理,让辅助代码单独生成到一个文件中,引入到编译后的文件中,而不是每个文件都生成辅助代码,从而减小打包后的体积。
npm i @babel/plugin-transform-runtime -D
// webpack.config.jsmodule.exports = {module: {rules: [{test: /.\.js$/,// 排除node_modules下的文件 不作处理exclude: /node_modules/,loader: 'babel-loader',options: {cacheDirectory: true, // 开启babel缓存cacheCompression: false, // 关闭缓存文件压缩plugins: ['@babel/plugin-transform-runtime'] // 减小代码体积}},]}
}
3. Image Minimizer 图片压缩
当项目中使用了很多本地图片,那么可以对图片进行压缩,减小图片体积,从而加快请求速度。如果项目中使用的是在线链接的图片,那么就不需要进行配置了。
npm i image-minimizer-webpack-plugin imagemin -D
安装完上面两个依赖包之后还需要下载另外两种压缩方式的包,读者选择性下载。
一是无损压缩:
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev
二是有损压缩:
npm install imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo --save-dev
// webpack.config.js
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const { extendDefaultPlugins } = require('svgo');module.exports = {module: {rules: [{test: /\.(jpe?g|png|gif|svg)$/i,type: 'asset',},],},plugins: [new ImageMinimizerPlugin({minimizerOptions: {plugins: [['gifsicle', { interlaced: true }],['jpegtran', { progressive: true }],['optipng', { optimizationLevel: 5 }],['svgo',{plugins: extendDefaultPlugins([{name: 'removeViewBox',active: false,},{name: 'addAttributesToSVGElement',params: {attributes: [{ xmlns: 'http://www.w3.org/2000/svg' }],},},]),},],],},}),]
}
优化代码性能
1. Code Split 代码分割
在进行打包时,会将所有的js文件打包到一个文件中,导致体积太大,加载速度慢。当使用了代码分割之后,生成多个js文件,渲染哪个页面就加载哪个js文件,这样就会减少资源的加载,速度就更快,从而提升性能。
使用:
一、多入口、多输出
module.exports = {entry: { // 多个入口文件,打包时就会产生多个输出文件main: './main.js',app: './src/app.js'},optimization: {splitChunks: { // 代码分割配置chunks: 'all', // 对所有模块都进行分割minSize: 20000, // 生成chunk的最小体积(以bytes为单位)minRemainingSize: 0, // 类似minSize,最后确保提取的文件大小不能为0minChunks: 1, // 至少被引用的次数,满足条件才会代码分割maxAsyncRequests: 30, // 按需加载时并行加载文件的最大数量maxInitialRequests: 30, // 入口js文件最大并行请求数量enforceSizeThreshold: 50000, // 超过50KB一定会单独打包(此时会忽略minRemainingSize、maxAsyncRequests、maxInitialRequests)cacheGroups: { // 组,指哪些模块要打包到一个组defaultVendors: { // 组名test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块priority: -10, // 权重,数值越大权重越高reuseExistingChunk: true, // 如果当前chunk包含已从主bundle中拆分出的模块,则它将被重用,而不是生成新的模块},default: { // 默认属性,没有就会使用上面的配置,此配置会覆盖上面的配置minChunks: 2,priority: -20,reuseExistingChunk: true,},},}}
}
二、单入口,多输出
module.exports = {entry: './main.js',optimization: {splitChunks: {chunks: 'all'}}
}
2. Preload / Prefetch 预加载 预获取
preload:使浏览器立即加载资源;prefetch:等待浏览器空闲时开始加载资源。它们只会加载资源,并不执行且都有缓存。Preload加载优先级要高于Prefetch。
npm install --save-dev @vue/preload-webpack-plugin
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin');module.exports = {plugins: [new PreloadWebpackPlugin({rel: 'preload', // 预加载的relas: 'script', // 预加载的资源类型include: 'allChunks' // 预加载的文件范围 // 或者使用 prefetchrel: 'prefetch'})]
}
3. Network Cache
对输出资源的文件更好的命名,可以做好缓存,提升性能。只对修改的文件打包之后改动文件名,其它文件不因引入改动的文件而改动文件名,可以更好的做到缓存。
module.exports = {optimization: {runtimeChunk: {name: entrypoint => `runtime~${entrypoint.name}.js`}}
}
4. Core-js 解决兼容性
例如一些ES6的新语法,babel无法处理,例如async函数、promise对象、数组的一些方法等等。所以可以使用core-js专门处理ES6及以上的语法。更好的适配老款浏览器的兼容性。
npm i core-js
安装好之后在主入口引入即可
import 'core-js'
5. PWA 渐进式网络应用程序(progressive web application - PWA)
当网络断开时,就无法访问Web应用了。为了提供离线访问效果,我们可以引入PWA,内部是通过Service Works技术实现的。可以将所有资源缓存到ServiceWork中,当离线时依旧可以访问。
npm install workbox-webpack-plugin --save-dev
const WorkboxPlugin = require('workbox-webpack-plugin');module.exports = {entry: {app: './src/index.js',print: './src/print.js',},plugins: [new HtmlWebpackPlugin({title: 'Output Management',title: 'Progressive Web Application',}),new WorkboxPlugin.GenerateSW({// 这些选项帮助快速启用 ServiceWorkers// 不允许遗留任何“旧的” ServiceWorkersclientsClaim: true,skipWaiting: true,}),],output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),clean: true,},};
最后,需要在主入口文件中注册Service Worker才能生效:
main.js
if ('serviceWorker' in navigator) {window.addEventListener('load', () => {navigator.serviceWorker.register('/service-worker.js').then(registration => {console.log('SW registered: ', registration);}).catch(registrationError => {console.log('SW registration failed: ', registrationError);});});}
相关文章:
Webpack5 常用优化总结
本文主要总结经常用到的一些代码性能优化、减小代码体积、提升webpack打包构建速度等内容的方法。具体的实现可参考webpack官网查看相关示例。 注:如果读者还未接触过webpack,请先了解webpack的基本使用。 正文: SourceMap ---- 提升开发体…...
Oracle-视图与索引
视图 简介 视图是一种虚表 视图建立在已有表的基础上,视图赖以建立的的这些表成为基表 向视图提供的数据的内容的语句的select 语句,可以将视图理解为存储起来的select 语句 视图向用户提供基表数据的另外一种表现形式 视图的好处 控制数据访问 …...

在Linux写自己的第一个程序“hello Linux”
01.nano指令 我们在Windows中有很多的编译环境,大家应该都很熟悉,但是在Linux中,我们怎么写代码呢? 这里,我介绍一个非常简单的指令->nano 这个指令就类似于我们Windows中的记事本,使用方法也很简单 …...

【AI视野·今日Robot 机器人论文速览 第六十八期】Tue, 2 Jan 2024
AI视野今日CS.Robotics 机器人学论文速览 Tue, 2 Jan 2024 Totally 12 papers 👉上期速览✈更多精彩请移步主页 Daily Robotics Papers Edge Computing based Human-Robot Cognitive Fusion: A Medical Case Study in the Autism Spectrum Disorder Therapy Author…...

图像识别快速实现
文本的跑通了,接下来玩玩图片场景 1. 引入模型 再另起类test_qdrant_img.py,转化图片用到的模型和文本不太一样,我们这里使用ResNet-50模型 import unittest from qdrant_client.http.models import Distance, VectorParams from qdrant_cl…...

一文详解动态 Schema
在数据库中,Schema 常有,而动态 Schema 不常有。 例如,SQL 数据库有预定义的 Schema,但这些 Schema 通常都不能修改,用户只有在创建时才能定义 Schema。Schema 的作用是告诉数据库使用者所希望的表结构,确保…...
Web网页开发-总结笔记2
28.为什么会出现浮动?浮动会带来哪些问题? 1)为什么会出现浮动: 为了页面排版时块元素同行显示 2)浮动带来的问题: 父元素高度崩塌29.清除浮动的方法 (额外标签法、父级overflow、after伪元素、双伪元素) (…...
C#的StringBuilder方法
一、StringBuilder方法 StringBuilder方法Append()向此实例追加指定对象的字符串表示形式。AppendFormat()向此实例追加通过处理复合格式字符串(包含零个或更多格式项)而返回的字符串。 每个格式项都由相应的对象自变量的字符串表示形式替换。AppendJoi…...

美格智能5G RedCap模组SRM813Q通过广东联通5G创新实验室测试认证
近日,美格智能5G RedCap轻量化模组SRM813Q正式通过广东联通5G创新实验室端到端的测试验收,获颁测评证书。美格智能已连续通过业内两家权威实验室的测试认证,充分验证SRM813Q系列模组已经具备了成熟的商用能力,将为智慧工业、安防监…...

MVCC 并发控制原理-源码解析(非常详细)
基础概念 并发事务带来的问题 1)脏读:一个事务读取到另一个事务更新但还未提交的数据,如果另一个事务出现回滚或者进一步更新,则会出现问题。 2)不可重复读:在一个事务中两次次读取同一个数据时,…...

通过国家网络风险管理方法提供安全的网络环境
印度尼西亚通过讨论网络安全法草案启动了其战略举措。不过,政府和议会尚未就该法案的多项内容达成一致。另一方面,制定战略性、全面的网络安全方法的紧迫性从未像今天这样重要。 其政府官方网站遭受了多起网络攻击,引发了人们对国家网络安全…...
input中typedate的属性都有那些
自我扩展‘ type 中date属性 自我 控制编辑区域的 ::-webkit-datetime-edit { padding: 1px; background: url(…/selection.gif); }控制年月日这个区域的 ::-webkit-datetime-edit-fields-wrapper { background-color: #eee; }这是控制年月日之间的斜线或短横线的 ::-webki…...

将PPT4页并排成1页
将PPT4页并排成1页打印 解决方法: 方法一 在打印时选择: 打开 PPT,点击文件选项点击打印点击整页幻灯片点击4张水平放置的幻灯平页面就会显示4张PPT显示在一张纸上 方法二 另存为PDF: 打开电脑上的目标PPT文件,点击文件点击…...

iPhone 恢复出厂设置后如何恢复数据
如果您在 iPhone 上执行了恢复出厂设置,您会发现所有旧数据都被清除了。这对于清理混乱和提高设备性能非常有用,但如果您忘记保存重要文件,那就是坏消息了。 恢复出厂设置后可以恢复数据吗?是的!幸运的是,…...

欧洲最好的AI大模型:Mistral 7B!(开源、全面超越Llama 2)
你可能已经听说过Meta(原Facebook)的Llama 2,这是一款拥有13亿参数的语言模型,能够生成文本、代码、图像等多种内容。 但是你知道吗,有一家法国的创业公司Mistral AI,推出了一款只有7.3亿参数的语言模型&am…...

Python | 诞生、解析器的分类版本及安装
1. python的诞生 Python是一门由Guido van Rossum(龟叔)于1991年创造的高级编程语言。 下图是TIOBE指数(TIOBE Index)的官方网站的截图,TIOBE指数是衡量编程语言流行度的指标之一,截止到目前python排名第…...

vim学习记录
目录 历史记录前言相关资料配置windows互换ESC和Caps Lock按键 基本操作替换字符串 历史记录 2024年1月2日, 搭建好框架,开始学习; 前言 vim使用很久了,但是都是一些基本用法,主要是用于配置Linux,进行一些简单的编写文档和程序.没有进行过大型程序开发,没有达到熟练使用的程…...
bat脚本:将ini文件两行值转json格式
原文件 .ini:目标转换第2行和第三行成下方json [info] listKeykey1^key2^key3 listNameA大^B最小^c最好 ccc1^2^3^ ddd0^1^9目标格式 生成同名json文件,并删除原ini文件 [ { "value":"key1", "text":"A大" …...

scratch绘制小正方形 2023年12月中国电子学会图形化编程 少儿编程 scratch编程等级考试四级真题和答案解析
目录 scratch绘制小正方形 一、题目要求 1、准备工作 2、功能实现 二、案例分析...

【产品应用】一体化伺服电机在管道检测机器人中的应用
一体化伺服电机在管道检测机器人的应用正日益受到关注。管道检测机器人是一种能够在管道内部进行检测和维护的智能化设备,它可以检测管道的内部结构、泄漏、腐蚀等问题,以确保管道的安全和稳定运行。而一体化伺服电机作为机器人的动力源,对于…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...