webpack实战——代码分片
前言
这是webpack实战
系列笔记的第9篇记录——代码分片
,前几篇记录如下:
- 打包第一个应用
- 模块化与模块打包
- 资源输入与输出
- 一切皆模块
- 预处理器【上篇】
- 预处理器——常用loader【下篇】
- 样式文件分离
- 样式预处理
代码分片
“实现高性能应用其中重要的一点就是尽可能的让用户每次只加载必要的资源,优先级不太高的资源则采用延迟加载(懒加载)等技术渐进式的获取,这样可以保证首屏页面加载的速度。 代码分片是Webpack作为打包工具所特有的一项技术,通过这项技术我们可以把代码按照特定的形式进行拆分,使用户按需加载。
通过入口划分代码
通过入口配置进行一些简单有效的代码拆分。
对于web应用来说通常会有一些库和工具是不常变动的,可以将它们放在一个单独的入口中,由该入口产生的资源不会经常更新,因此可以有效地利用客户端缓存,让用户不必在每次请求页面时都让资源重新加载。
// webpack.config.js
...
entry:{
app: './src/app.js',
lib: ['lib-a', 'lib-b', 'lib-c']
}
<!--index.html-->
...
<script src="./dist/lib.js"></script>
<script src="./dist/app.js"></script>
这种拆分方法主要适用于那些将接口绑定在全局对象上的库,因为业务代码中的模块无法直接引用库中的模块,而这属于不同的依赖树。
但这样仍会带来新的问题:公共模块与业务模块处于不同依赖树的问题以及很多页面并不需要公共模块的问题。
optimization
在webpack4之前,做代码切片使用的是CommonsChunkPlugin,而在4及之后,取而代之的是optimization。
“optimization.SplitChunks简称optimization,是Webpack4为了改进CommonChunkPlugin而重新设计和实现的代码分片特性。
举例
1. 安装
// 两种方式二选一
yarn add optimization react
// 或
npm install optimization react
2. a.js & b.js
// a.js
import React from 'react'
import('./b.js');
document.write('a.js', React.version)
// b.js
import React from 'react'
console.log('b.js', React.version)
3. webpack配置
// webpack.config.js
module.exports = {
entry: './src/a.js',
output: {
filename: 'a.js',
publicPath: '/dist/'
},
mode: 'development',
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
4. 打包
yarn build
// 或
npm run build
结果如图所示:
点击查看大图
特性
首先观察上面的配置,从上面的配置项中可以看到:
- 指定了chunks的值是all,含义是:SplitChunks将会对所有的chunks生效;
- mode:之前也一直在用,其实是Webpack4中新增的配置项,可以针对当前是开发环境还是生产环境自动添加一些对应的Webpack配置。
而从上图打包结果中看,可以看到三个文件包:0.a.js
、a.js
和vendors~main.a.js
。其中,vendors~main.a.js
则是将react提取到了里面。
提取条件
- 提取后的chunk可被共享或者来自node_modules目录。
- 提取后的JS chunk体积大于30kB(压缩和gzip前),CSS chunk体积大于50kB。
- 按需加载过程中,并行请求的资源最大值小于等于5。
- 首次加载时,并行请求的资源数最大值小于等于3。
需要注意的是,默认提取方式为异步提取。
配置
分为四类:
- 匹配模式 通过chunks可以配置Splitchunks的工作模式:async(默认),initial和all。async即只提取异步chunk,initial只对入口chunk生效,all则两种模式同时开启。
- 匹配条件 minSize、minChunks、maxAsyncRequests、maxInitialRequests都属于匹配条件。
- 命名 配置项name默认为true,意味着SplitChunks可以根据CacheGroups和作用范围自动为新生成的chunk命名,并且以automaticNameDelimiter分割。
- CacheGroups 可以理解为分离chunks时的规则。
默认配置
module.exports = {
...
splitChunks: {
chunks: 'async',
miSize: {
javascript: 30000,
style: 50000,
},
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\/]node_modules[\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
小结
本篇了解了两种代码分片方式:
- 入口规划
- SplitChunks
而借助这些方法,我们可以有效的缩小资源体积,更好的利用缓存,从而给用户更有好的体验度。
下一篇介绍生产环境优化中的一些配置,如环境配置封装、sourceMap等。
- Keras中神经网络模型的5阶段生命周期
- java的断言(assert)
- Android studio中Rendering Problems不能可视化操作的解决办法
- 使用 Referer Meta 标签控制 referer—详解 referrer-policy
- 网站抓取引子 - 获得网页中的表格
- Android Firebase 服务简介
- CVE-2015-0393:Oracle发布严重安全漏洞预警
- 研究人员发现一种利用Siri窃取苹果iPhone/iPad数据的方法
- 关于Python中的__main__和编程模板
- 世界大战尽在掌控:盘点全球网络攻击实时追踪系统
- Activity数据传递
- apache反向代理一、泛解析域名二、APACHE配置
- Python学习 - 可视化变量赋值、循环、程序运行过程
- jdk源码分析红黑树——插入篇1.插入root2.父黑3.父红4.父红,叔红5.1父红,叔黑,外侧子孙5.2父红,叔黑,内侧子孙
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- k8s基本使用
- 淮师2017校园新闻爬取&&WordCloud年度词云分析
- 13 | Tornado源码分析:BaseIOStream 对象(下)
- 谈谈线程
- springboot整合定时框架-Elastic-job-lite
- hashMap的循环姿势你真的使用对了吗?
- SpringBoot整合常用技术
- SpringBoot整合Quartz实现定时任务(单任务、多任务)
- 你的登录接口,真的安全吗?如何预防黑客攻击
- JWT登录信息加密
- 我画了近百张图来理解红黑树
- SpringBoot之API--Swagger2接口文档管理
- 索引失效原理,终于有人讲明白了
- 你真了解你的系统吗?它要崩溃了
- 伸手党的容器镜像加固流程