性能优化的方式
1.**对打包后的结果进行优化(**分包处理,减小包的体积,使用cdn服务器)
2.优化打包速度(exclude,cache-loader)
一般更侧重于对打包后的结果进行优化。
默认情况下所有打包后的结果都会放到一个文件中,如自己编写的代码,第三方库react,axios,dayjs等都会打包到一个文件中,这就需要对代码进行分离
代码分离
代码分离的方式主要有3种:
入口起点:可以配置多个entry入口
去除重复代码:使用Entry Dependencies 或SplitChunksPlugin去重和分离代码
动态导入:通过调用模块的内联函数来分离代码
多入口
webpack
entry: {
main: "./src/main.js",
index: "./src/index.js",
},
//这里要注意打包后的文件名称要不同 所以使用了[name]
output: {
filename: "[name]-bundle.js",
path: path.resolve(__dirname, "./build"),
clean: true,
},
index.html中可以不同导入脚本,打包后的html会自动导入脚本。
打包后的html:
打包后的文件目录:
多入口共享公共的依赖
entry: {
main: {
import: "./src/main.js",
dependOn: "shared",
}, //shared可以是任意的
index: {
import: "./src/index.js",
dependOn: "shared",
},
shared: "dayjs", //[]数组形式可以共享多个
},
output: {
filename: "[name]-bundle.js",
path: path.resolve(__dirname, "./build"),
clean: true,
},
在main和index中使用:
打包后的目录:
动态导入
使用ECMAScript的import()动态导入,在用到对应的组件时才会加载。动态导入主要用于懒加载(比如路由懒加载)
打包后的文件
打开页面后它默认是不会加载动态导入的组件的
当使用到异步组件时才会加载
使用动态导入会分包,可以使用chunkFilename对分包的文件进行命名
还需要使用注释配置webpackChunkName
btn1.addEventListener("click", () => {
import(/* webpackChunkName: "content1" */ "./content1.js");
});
btn2.addEventListener("click", () => {
import(/* webpackChunkName: "content2" */ "./content2.js").then((res) => {
// 动态导入的实际上是一个对象。导出的内容在default属性上
console.log(res);
});
});
打包后的目录:
Splitchunks
Splitchunks 是使用SplitChunksPlugin来实现分包的,webpack已经默认安装了,不需要再安装。
webpack的SplitChunksPlugin提供了默认的配置,默认情况下它只会影响到按需加载的 chunks。
默认的配置:
Splitchunks 的配置
chunks: 默认值是async,all标识对同步和异步的代码都进行处理。
minSize:拆分包的大小,至少为minSize,小于minSize的包不会拆分。
maxSize:拆分包的大小,将大于maxSize的包拆分为不小于minSize的包。
cacheGroups: 对拆分的包进行分组。
test: 匹配符合规则的包
name:拆分包的name属性
filename:拆分包的名称,可以使用自己的placeholder属性
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
devtool: "source-map",
entry: {},
output: {},
resolve: {},
module: {},
plugins: [ ],
devServer: {},
optimization: {
splitChunks: {
chunks: "all",
//
maxSize: 20000,
//将包拆成不小于minSize的包,如果打不到minSize,那么这个包就不会拆分(会被合并到其他包中)
minSize: 10000,
cacheGroups: {
venders: {
//匹配/node_modules/下的包 [\\/] /node_modules和\node_modules 为了处理不同系统的问题
// \\ 第一个\是为了转意,有些字符有特殊含义
test: /[\\/]node_modules[\\/]/,
filename: "[id]_[hash:6]_vender.js",
},
foo: {
test: /utils/,
filename: "[id]_[hahs:6]_utils.js",
},
},
},
},
};
打包后的文件:
chunkIds webpack模块中的采用什么算法生成
常见的值:
开发过程中推荐使用natural,打包过程中推荐使用deterministic。
...
module: []
plugins:[],
devServer:{},
optimization: {
splitChunks: {},
chunkIds: "deterministic",
},
Prefetch和Preload 预获取和预加载
在使用import() 导入时可以使用:
Prefetch:将来某些导航下要获取的资源
Preload:当前导航下可能要获取的资源
使用Preload的chunk会在父chunk加载时,以并行的方式开始加载,而Prefetch的会在父chunk加载完后再加载。
Preload的chunk优先级高一点,会立即下载,Prefetch的会在浏览器闲暇时刻下载
Preload的chunk会在父chunk中立即请求,在当下使用Prefetch在未来使用
使用