webpack4的splitChunksPlugin配置参数详解---代码分割 、懒加载以及prefetching 和 preloading

代码啊分割

  • 如果把 一个 应用的 所有代码 都打包到 一个文件,如果文件过于庞大,首次加载 会非常 缓慢,同时 加载了 没使用的 模块,因此 可以把 这些代码模块 分割成 单独一个文件,运行时 再去加载。使用webpack4.x的 splitChunksPlugin插件 可以帮助我们实现代码分割,替代了 之前的 commonsChunkPlugin插件。

参数详解

module.exports = {
    mode: 'development',
    // 下面这里是默认值
    entry: {
        // 入口文件名的键 main (下面简称 入口文件)
        main: './src/index.js'
    },
    output: {
        filename: '[name].bound.js',
        path: path.resolve(__dirname, '../dist'),
    },
    ...
    optimization{
        splitChunks: {
            /**
                1. 三个值 
                    async 仅提取按需载入的module
                    initial 仅提取同步载入的module
                    all 按需、同步都有提取
            */
            chunks: "async",
            // 只有导入的模块 大于 该值 才会 做代码分割 (单位字节)
            minSize: 30000,
            // 提取出的新chunk在两次压缩之前要小于多少kb,默认为0,即不做限制
            maxSize: 0,
            // 被提取的chunk最少需要被多少chunks共同引入
            minChunks: 1,
            // 按需加载的代码块(vendor-chunk)并行请求的数量小于或等于5个
            maxAsyncRequests: 5, 
            // 初始加载的代码块,并行请求的数量小于或者等于3个
            maxInitialRequests: 3,
            // 默认命名 连接符
            automaticNameDelimiter: '~',
            /**
                name 为true时,分割文件名为 [缓存组名][连接符][入口文件名].js
                name 为false时,分割文件名为 [模块id][连接符][入口文件名].js
                如果 缓存组存在 name 属性时 以缓存组的name属性为准
            */
            name: true,
            // 缓存组 当符合 代码分割的 条件时 就会进入 缓存组 把各个模块进行分组,最后一块打包
            cacheGroups: {
                // 如果 引入文件 在node_modules 会被打包 这个缓存组(vendors)
                vendors: {
                    // 只分割 node_modules文件夹下的模块
                    test: /[\/]node_modules[\/]/,
                    // 优先级 因为如果 同时满足 vendors、和default 哪个优先级高 就会打包到哪个缓存组
                    priority: -10
                },
                default: {
                    // 表示这个库 至少被多少个chunks引入,
                    minChunks: 2,
                    priority: -20,
                    // 如果 这个模块已经 被分到 vendors组,这里无需在分割 直接引用 分割后的
                    reuseExistingChunk: true
                }
            }
        }
    }    
}    

简单打包

  • 上面的配置 基本不变,只修改一些内容
// math.js 
export default function(){
    console.log('add')
}

// index,js
// 非 node_modules 模块
import add from './math'
// node_modules 模块
import axios from 'axios'

add()
axios({})

// 修改配置
minSize: 1, //因为 math.js 文件过小 表示 大于1字节 就做代码分割
minChunks: 2, // 把它去掉 即不做限制

// 打包结果
default~main.bound.js  221 bytes // math.js 打包文件
default~main.bound.js.map  125 bytes
               index.html  533 bytes
            main.bound.js   1.51 KiB // 入口文件
        main.bound.js.map  109 bytes 
    vendors~main.bound.js   14.7 KiB // axios 打包文件
vendors~main.bound.js.map  125 bytes 

懒加载

  • 或者说 按需加载,首次并不会 加载 全部 模块,这样可以提高首次响应的人速度。
// index.js 文件替换成这样 页面 增加一个按钮 id为 btn
// 点击 按钮 后再去加载 axios
document.querySelector('#btn1').addEventListener('click', function(){
    import('axios').then(() =>{
        console.log('懒加载 axios')
    })
})

结果

prefetching 和 preloading

prefetching

  • 当我们 使用 某个功能 再去加载响应的 模块,无疑也会 消耗一定的性能,如果能做到 当核心 代码加载完毕,偷偷的去加载 这些暂时还没用到的 模块,当使用到该模块 直接从缓存读取资源。没错 prefetching 可以帮助我们做到。
// index.js 文件替换成这样 页面 增加一个按钮 id为 btn
document.querySelector('#btn1').addEventListener('click', function(){
    import(/* webpackPrefetch: true */'axios').then(() =>{
        console.log('懒加载 axios')
    })
})

结果

preloading

  • 把 /* webpackPrefetch: true / 修改为 / webpackPreload: true */,preloading的模块 与 核心模块 一起加载,会消耗 首次加载的 性能。而 prefetching 相反。

说明

  • 这里面 还有很多 细节问题,只有用多了,才会 注意 里面的 一些问题,有两个 参数 maxAsyncRequests、maxInitialRequests,虽然说 使用默认 即可,但是理解起来还是有点难,估计要结合webpack的打包原理,下次再总结一下,如有错误,恳请多多指教哈。
原文地址:https://www.cnblogs.com/HJ412/p/12405022.html