当前位置: 首页 > 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、功能实现 二、案例分析...

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

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

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

ES6从入门到精通:前言

ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则&#xf…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 ​二、实现思路 总体思路: 用户通过Gradio界面上…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)

目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 ​编辑​编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...

用递归算法解锁「子集」问题 —— LeetCode 78题解析

文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...