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、功能实现 二、案例分析...
【产品应用】一体化伺服电机在管道检测机器人中的应用
一体化伺服电机在管道检测机器人的应用正日益受到关注。管道检测机器人是一种能够在管道内部进行检测和维护的智能化设备,它可以检测管道的内部结构、泄漏、腐蚀等问题,以确保管道的安全和稳定运行。而一体化伺服电机作为机器人的动力源,对于…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
初学 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…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
