当前位置: 首页 > news >正文

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伪元素、双伪元素) &#xff08…...

C#的StringBuilder方法

一、StringBuilder方法 StringBuilder方法Append()向此实例追加指定对象的字符串表示形式。AppendFormat()向此实例追加通过处理复合格式字符串(包含零个或更多格式项)而返回的字符串。 每个格式项都由相应的对象自变量的字符串表示形式替换。AppendJoi…...

美格智能5G RedCap模组SRM813Q通过广东联通5G创新实验室测试认证

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

MVCC 并发控制原理-源码解析(非常详细)

基础概念 并发事务带来的问题 1)脏读:一个事务读取到另一个事务更新但还未提交的数据,如果另一个事务出现回滚或者进一步更新,则会出现问题。 2)不可重复读:在一个事务中两次次读取同一个数据时&#xff0c…...

通过国家网络风险管理方法提供安全的网络环境

印度尼西亚通过讨论网络安全法草案启动了其战略举措。不过,政府和议会尚未就该法案的多项内容达成一致。另一方面,制定战略性、全面的网络安全方法的紧迫性从未像今天这样重要。 其政府官方网站遭受了多起网络攻击,引发了人们对国家网络安全…...

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、功能实现 二、案例分析...

【产品应用】一体化伺服电机在管道检测机器人中的应用

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

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...

golang循环变量捕获问题​​

在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下: 问题背景 看这个代码片段: fo…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

ip子接口配置及删除

配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域,Hive 作为 Hadoop 生态中重要的数据仓库工具,其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式,很多开发者常常陷入选择困境。本文将从底…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...