webpack 打包优化 - splitChunks

打包时会遇到的问题:

  1. 打包文件过大,首屏加载时间过长,js阻塞页面渲染导致白屏
  2. 改动业务代码后,对于第三方库也会一并重新打包到一个出口文件,浏览器无法利用缓存来减少请求和加载的时间

针对以上两个问题,利用splitChunks可以将各个模块进行分割,并提取出相同部分代码,从而缓解一个js过大、不能缓存第三方库的问题。

webpack 从 4.x 开始支持了零配置的特性,同时对块打包也做了优化,CommonsChunkPlugin已经被移除了,现在是使用optimization.splitChunks代替。(webpack5 splitChunks 配置和 webpack4 大体上一样)

概念区分 - module、bundle、chunk都是什么?

在说SplitChunks前,先来了解几个概念,module、bundle、chunk都是什么?

module:模块,在webpack中任何文件都可以作为一个模块,借用官网的图片,左侧的这些类型文件,都可以认为是一个模块,只是需要配置不同的loader,将文件转换成webpack可以支持打包的文件。

chunk:编译完成准备输出时,webpack 将module 按特定规则组成的一个个 chunk

bundle:webpack 处理好chunk文件后,生成运行在浏览器中的代码

SplitChunks 插件是什么呢

简单的来说就是 Webpack 中一个提取或分离代码的插件,主要作用是提取公共代码,防止代码被重复打包,拆分过大的js文件,合并零散的js文件。

提到前端优化,提取公共代码是必不可少的手段。
在 Webpack 出现前,提取公共代码是人为去处理,而 SplitChunks 插件的作用就是通过配置让 Webpack 去帮你提取公共代码。SplitChunksPlugin 默认配置适用大部分场景。

打包默认情况下只会影响按需加载模块,因为对初始块也进行优化打包会影响 HTML 中的 script 标签数,增加请求数。

默认情况(webpack 的默认配置)下 webpack 会根据下述条件自动进行代码块分割:

  • 共享模块(至少被引用 2次)或者 node_modules 模块
  • 新代码块大于 20kb(min+gziped之前的体积)
  • 按需加载块时的最大并行请求数将低于或等于 30
  • 初始页面加载时的最大并行请求数将低于或等于 30

SplitChunks插件配置选项

  • 同步加载的模块:通过 import xxx 或 require(‘xxx’) 加载的模块。
  • 异步加载的模块:通过 import(‘xxx’) 或 require([‘xxx’],() =>{}) 加载的模块。
  • chunks: 表示哪些代码需要优化,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),chunks 选项,决定要提取哪些模块
    • 默认是 async :只提取异步加载的模块出来打包到一个文件中。
    • initial 模块下只优化初始模块,也就是说 webpack 只会对初始模块做打包优化。如果 xxx 在项目中异步加载了,也同步加载了,那么 xxx 这个模块会被提取两次,分别打包到不同的文件中。
    • all 模块下同时对初始模块和异步模块做打包优化,不管异步加载还是同步加载的模块都提取出来,打包到一个文件中。
  • minSize: 规定被提取的模块在压缩前的大小最小值,单位为字节。表示在压缩前的最小模块大小,默认为 20000
  • minChunks: 表示被引用次数,默认为 1
  • maxAsyncRequests: 按需加载时候最大的并行请求数,默认为 30
  • maxInitialRequests: 一个入口最大的并行请求数,默认为 30
  • enforceSizeThreshold:强制执行拆分的体积阈值
  • cacheGroups: 缓存组。缓存组的属性除上面所有属性外,还有 test, priority, reuseExistingChunk
    • test: 用于控制哪些模块被这个缓存组匹配到
    • priority: 缓存组打包的先后优先级
    • reuseExistingChunk: 如果当前代码块包含的模块已经有了,就不在产生一个新的代码块

实际使用情景:

1. 设置 chunks: initial || all 都可以提取出第三方库。但是它是把所有第三库提取出来,所以我们在只提取 react 和 react-dom 的情况下,需要自定义一个 cacheGroup。

// webpack.config.js
optimization: {
  splitChunks: {
    chunks: 'all',
    cacheGroups: {
      react: {
          name: 'react',
          test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
      }
    }
  }
}

安装  webpack-bundle-analyzer, 可以查看打包体积情况,在package.json 中,npm run build 的地方写一个 --report 就会在打包文件中生成一个 report.html, 打开可以看到打包体积情况。  "build": "vue-cli-service build --report"

2. 比如发现chunk-vendors.js的大小有点大了,有1.91MB,还是项目初始化时需要加载的 js 文件,大小过大会导致首屏加载时间过长。

要优化一下,两种方法:可以用SplitChunks优化。

例如要把element从chunk-vendors.js提取出来,就在cacheGroups 进行对应配置:

chainWebpack(config) {
        config.when(process.env.NODE_ENV != 'development',
        config => {
            config.optimization.splitChunks({
                chunks: 'all',
                cacheGroups: {
                    // 第三方组件
                    libs: {
                        // 指定chunks名称
                        name: 'chunk-libs',
                        //符合组的要求就给构建venders
                        test: /[\\/]node_modules[\\/]/,
                        //priority:优先级:数字越大优先级越高,因为默认值为0,所以自定义的一般是负数形式,决定cacheGroups中相同条件下每个组执行的优先顺序。
                        priority: 10,
                        // 仅限于最初依赖的第三方
                        chunks: 'all'
                    },
                    elementUI: {
                        // 将elementUI拆分为单个包
                        name: 'chunk-elementUI',
                        // 重量需要大于libs和app,否则将打包到libs或app中
                        priority: 20,
                        // 为了适应cnpm
                        test: /[\\/]node_modules[\\/]_?element-ui(.*)/
                    },
                    //公共组件
                  //   commons: {
                  //       name: 'chunk-commons',
                  //       // can customize your rules
                  //       test: resolve('src/components'),
                  //       minChunks: 3,
                  //       priority: 30,
                  //       //这个的作用是当前的chunk如果包含了从main里面分离出来的模块,则重用这个模块,这样的问题是会影响chunk的名称。
                  //       reuseExistingChunk: true,
                  //       //最大初始化加载次数,一个入口文件可以并行加载的最大文件数量,默认3
                  //       maxInitialRequests: 3,
                  //       //表示在分离前的最小模块大小,默认为0,最小为30000
                  //       minSize: 0
                  //   },
                }
            })
        })

    }

总结:

webpack5 默认情况下只对异步模块做打包优化,额外的打包必须满足 4 个条件(webpack 的默认配置,可修改)。根据需求可调整为只对初始模块做打包优化,或者初始和异步模块一起优化。同时可配置自己的打包规则。

简而言之:chunks 控制打包作用范围,其他控制打包规则。

webpack5 的 splitChunks 功能是比较强大的,不过推荐还是使用默认模式,或者提取一下第三方库。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/558743.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Excel中将单元格格式改成文本后,为何要双击数字才会改变?

将大批量的数值型数字转换成文本型数字,当然不能一个一个的去双击做转换了。以下说说有哪个可以将数值型数字转换成文本型数字的方法。 一、转换方法 方法1.数据分列功能 选中数据后,点击数据选项卡,分列, 分列向导的第一步和…

部署轻量级Gitea替代GitLab进行版本控制(一)

Gitea 是一款使用 Golang 编写的可自运营的代码管理工具。 Gitea Official Website gitea: Gitea的首要目标是创建一个极易安装,运行非常快速,安装和使用体验良好的自建 Git 服务。我们采用Go作为后端语言,这使我们只要生成一个可执行程序即…

ACL的基本配置

已经启用rip实现了全网可达。 这时我们要拒绝R1与R4的路由通信,做标准ACL过滤关注源IP需要尽量靠近目标。则在R4的物理接口G0/0/1的in接口上做,不能在R4的环回接口上做,因为ACL列表…

【Taro3踩坑日记】找不到sass的类型定义文件

问题截图如下:找不到sass的类型定义文件 解决办法: 1、npm i types/sass1.43.1 2、然后配置 TypeScript 编译选项:确保 TypeScript 编译器能够识别 Sass 文件,并正确处理它们。

小程序 前端如何用wx.request获取 access_token接口调用凭据

在微信小程序中,获取access_token通常是通过wx.request方法来实现的。以下是一个简单的示例代码: 1.获取小程序的appID 与 secret(小程序密钥) 登录之后,请点击左侧的"开发管理">点击"开发设置" 就可以找…

在Ubuntu 22.04上安装配置VNC实现可视化

前面安装的部分可以看我这篇文章 在Ubuntu 18.04上安装配置VNC实现Spinach测试可视化_ubuntu18开vnc-CSDN博客 命令差不多一样: sudo apt update sudo apt install xfce4 xfce4-goodies sudo apt install tightvncserver这个时候就可以启动server了 启动server&…

.net8系列-01手把手教你创建一个新的.net应用(.net7和.net8的不同点)以及三种方案进行接口调试

前提条件 如果没有安装VS2022.17.8 版本环境,请参考我的.net系列其他安装步骤文章来进行安装(发布本文的时候另一篇文章正在审核无法放链接,等后续补充哦,也可以自己搜索我的博文哦~很齐全) Windows版本.net环境搭建…

iOS -- 工厂设计模式

iOS -- 工厂设计模式 设计模式概念设计模式七大准则简单工厂模式优点缺点主要作用示例 工厂方法模式优点缺点主要作用: 抽象工厂方法缺点主要作用:文件分类 设计模式概念 所谓设计模式(Design pattern) 是解决软件开发某些特定问…

nginx installed inLinux

yum install nginx [rootmufeng ~]# yum install nginx CentOS系列:【Linux】CentOS7操作系统安装nginx实战(多种方法,超详细) ———————————————— 版权声明:本文为博主原创文章,遵循 CC …

Maven通过flatten-maven-plugin插件实现多模块版本统一管理

正文 起因是公司开始推代码版本管理的相关制度,而开发过程中经常使用多模块构建项目,每次做版本管理时都需要对每个模块及子模块下的pom文件中parent.version和模块下依赖中的version进行修改,改的地方非常多,且非常容易漏。为此…

Pytorch 学习路程

目录 下载Pytorch 入门尝试 几种常见的Tensor Scalar Vector Matrix AutoGrad机制 线性回归尝试 使用hub模块 Pytorch是重要的人工智能深度学习框架。既然已经点进来,我们就详细的介绍一下啥是Pytorch PyTorch 希望将其代替 Numpy 来利用 GPUs 的威力&…

深度学习pytorch实战4---猴逗病识别·

>- **🍨 本文为[🔗365天深度学习训练营](https://mp.weixin.qq.com/s/0dvHCaOoFnW8SCp3JpzKxg) 中的学习记录博客** >- **🍖 原作者:[K同学啊](https://mtyjkh.blog.csdn.net/)** 引言 1.复习上周并反思 K同学针对大家近…

【数据结构】图论(图的储存方式,图的遍历算法DFS和BFS、图的遍历算法的应用、图的连通性问题)

目录 图论一、 图的基本概念和术语二、图的存储结构1. 数组(邻接矩阵)存储表示无向图的数组(邻接矩阵)存储表示有向图的数组(邻接矩阵)存储表示 邻接表存储表示有向图的十字链表存储表示无向图的邻接多重表存储表示 三、图的遍历算法图的遍历——深度优先搜索(DFS&a…

FPGA_verilog语法整理

FPGA_verilog语法整理 verilog的逻辑值 verilog的常数表达 位宽中指定常数的宽度(表示成二进制数的位数),单引号加表示该常数为几进制的底数符号。 二进制底数符号为b,八进制为 o,十进制为d,十六进制为 h…

递归、搜索与回溯算法——穷举vs暴搜vs深搜

T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 小比特 大梦想 此篇文章与大家分享递归、搜索与回溯算法关于穷举vs暴搜vs深搜的专题 如果有不足的或者错误的请您指出! 目录 1.全排列1.1解析1.2题解 2.子集2.1解析2.1.1解法12.1.2解法1代码2.1.3解法22.1.4解法…

vscode微博发布案例

样例: CSS代码: * {margin: 0;padding: 0; }ul{list-style: none; }.w {width: 900px;margin: 0 auto; }.controls textarea {width: 878px;height: 100px;resize: none;border-radius: 10px;outline: none;padding-left: 20px;padding-top: 10px;font-size: 18px; }.controls…

yolov8 区域计数

yolov8 区域计数 1. 基础2. 计数功能2.1 计数模块2.2 判断模块 3. 主代码4. 实验结果5. 源码 1. 基础 本项目是在 WindowsYOLOV8环境配置 的基础上实现的,测距原理可见上边文章 2. 计数功能 2.1 计数模块 在指定区域内计数模块 def count_objects_in_region(bo…

Redis: 在项目中的应用

文章目录 一、Redis的共享session应用二、分布式缓存1、缓存2、缓存一致性问题解决方案(缓存更新策略)(1)作用(2)三种策略(3)主动更新策略(数据库、缓存不一致解决方案&a…

SSL证书在HTTP与HTTPS中的角色差异是什么?

在互联网的广泛应用背景下,随着网络攻击和数据泄露事件频发,保障用户的数据安全已成为至关重要的议题。传统的HTTP协议在传输数据时不进行加密处理,导致数据在传输过程中暴露于潜在的窃听和篡改风险中,安全性薄弱。而通过引入SSL/…

【HC32L110】华大低功耗单片机启动文件详解

本文主要记录华大低功耗单片机 HC32L110 的 汇编启动过程,包括startup_hc32l110启动文件详细注释 目录 1.启动文件的作用2.堆栈定义2.1 栈2.2堆 3.向量表4.复位程序5.中断服务程序6.堆栈初始化启动过程详解7.1从0地址开始7.2在Reset_Handler中干了啥? 8.…
最新文章