code spliting 把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。

代码分离可以用于获取更小的 bundle,以及控制资源加载优先级,如果使用合理,会极大缩减加载时间。

首先,看一组概念。参考:https://www.jianshu.com/p/a1ccd6d1b4ba

chunk:块,指若干个js module的集合
bundle:形式上是块的集合,意义是代表一个可以运行的整体
chunk和bundle:what-are-module-chunk-and-bundle-in-webpack
比较难说明,搜的基本都是个人总结,官方描述也比较抽象。
一个js文件就是一个模块,若干个js模块会打包成一个总的js文件,这个js文件称作bundle。但如果是多页面应用,往往会安排为一个html对应一个bundle,那么两个html的bundle之间重复的模块就是重复代码。此时我们会把这两个bundle重复的模块抽出来,称为common chunk,余下的两部分直接称作两个chunk。即此时一共有3个chunk,但依然只有两个bundle。
单页面应用中异步加载,或者单纯想分离出不变的第三方库,均可采用该手段进行优化。

有三种常用的代码分离方法:

  1. 入口起点:使用 entry 配置手动地分离代码(多页面应用;存在重复引用)。

    entry: {
    index: './src/index.js',
    another: './src/another-module.js'
    },

    another-module.js与index.js中,都存在lodash引用。

  2. 防止重复:使用 SplitChunksPlugin 去重和分离 chunk。(使用SplitChunksPlugin不需要安装任何依赖,只需在配置中添加 optimization 属性)

当满足以下条件时,来自相同块chunk和缓存组的模块将形成一个新块。

  • minSize (默认值:30000)块的最小大小
  • minChunks (默认值:1)在拆分之前共享模块的最小块数(a. 可以是来自node_modules b. 在两个或两个以上的引入调用共享)
  • maxInitialRequests (默认值为3)入口点的最大并行请求数
  • maxAsyncRequests (默认为5)按需加载时并行请求的最大数量

官网对splitChunks给出的默认配置如下:

optimization:{
splitChunks: {
chunks: "async",
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
  default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
cacheGroups(缓存组) 在默认设置中,会将 node_mudules 文件夹中的模块打包进一个叫 vendors的bundle中,所有引用超过两次的模块分配到 default bundle 中。更可以通过 priority 来设置优先级。

3. 动态导入:通过模块的内联函数调用来分离代码。

在webpack.prod.js中添加:

output:{
chunkFilename: '[name].bundle.js' // 非入口chunk的文件名
}

在index.js中使用动态加载的方式加载lodash

function component() {
return import(/* webpackChunkName: "lodash" */ 'lodash').then(_ => {
let element = document.createElement('div'); element.innerHTML = _.join(['hello','webpack,', cube(5)],' ');
element.classList.add('hello'); let button = document.createElement('button');
button.innerHTML = 'click me and check the console!'; button.onclick = myPrint; element.appendChild(button); return element;
}).catch(err => 'an error occured while loading the component'); } // 动态加载
component().then(element => {
document.body.appendChild(element);
if (module.hot) { //告诉 webpack 接受热替换的模块
module.hot.accept('./print.js', () => {
console.log('Accepting the updated printMe module!');
document.body.removeChild(element); //删掉旧的element
element = component(); //重新渲染页面后,component 更新 click 事件处理
document.body.appendChild(element); //重新插入到网页中
})
}
})

由此,lodash会单独形成一个chunk

在注释中使用了 webpackChunkName。这样做会导致我们的 bundle 被命名为 lodash.bundle.js ,而不是 [id].bundle.js.

由于 import() 会返回一个 promise,因此它可以和 async 函数一起使用。但是,需要使用像 Babel 这样的预处理器和Syntax Dynamic Import Babel Plugin

async function component() {
let element = document.createElement('div'); const _ = await import(/* webpackChunkName: "lodash" */ 'lodash')
element.innerHTML = _.join(['hello','webpack,', cube(5)],' ');
element.classList.add('hello'); let button = document.createElement('button');
button.innerHTML = 'click me and check the console!';
button.onclick = myPrint; element.appendChild(button);
return element;
}

懒加载  当发生用户交互时,再加载被分离的块。

在上述code spliting代码中,虽然lodash被单独分离成一个chunk。但分离后lodash加载与用户交互没有任何联系,换句话说,每次加载页面时都会去请求它。

async function component() {
let element = document.createElement('div'); let button = document.createElement('button');
button.innerHTML = 'click me and check the console!';
// 懒加载
button.onclick = e => import(/* webpackChunkName: "print" */ './print.js').then(module => {
const print = module.default;
print();
}) element.appendChild(button);
return element;
}

点击后,

注意:当调用 ES6 模块的 import() 方法引入模块时,必须指向module.default ,因为它才是 promise 被处理后返回的实际的 module 对象。

Vue懒加载:  https://alexjover.com/blog/lazy-load-in-vue-using-webpack-s-code-splitting/

React懒加载: https://reacttraining.com/react-router/web/guides/code-splitting

webpack指南(二)code spliting+懒加载的更多相关文章

  1. Webpack探索【16】--- 懒加载构建原理详解(模块如何被组建&如何加载)&源码解读

    本文主要说明Webpack懒加载构建和加载的原理,对构建后的源码进行分析. 一 说明 本文以一个简单的示例,通过对构建好的bundle.js源码进行分析,说明Webpack懒加载构建原理. 本文使用的 ...

  2. webpack多页面开发与懒加载hash解决方案

    之前讨论了webpack的hash与chunkhash的区别以及各自的应用场景,如果是常规单页面应用的话,上篇文章提供的方案是没有问题的.但是前端项目复杂多变,应对复杂多页面项目时,我们不得不继续踩w ...

  3. Webpack探索【10】--- 懒加载详解

    本文主要讲懒加载方面相关内容.

  4. webpack散记---代码分割 和 懒加载

    webpack methods ES 2015 Loader spec (1)webpack methods方法 require.ensure //可以动态加载依赖 []:dependencies / ...

  5. 在webpack中使用Code Splitting--代码分割来实现vue中的懒加载

    当Vue应用程序越来越大,使用Webpack的代码分割来懒加载组件,路由或者Vuex模块, 只有在需要时候才加载代码. 我们可以在Vue应用程序中在三个不同层级应用懒加载和代码分割: 组件,也称为异步 ...

  6. webpack打包懒加载

    lazyload https://webpack.js.org/guides/lazy-loading/ 懒加载 -- 按需加载. Lazy, or "on demand", lo ...

  7. vue项目性能优化(路由懒加载、gzip加速、cdn加速)

    前端工程性能优化一说意义深远悠长,本章主要介绍除了一些基础优化外如何实行路由懒加载.Gzip加速.CDN加速,让网页飞的快一些. 基础优化 老生常谈的一些: 不要在模板中写复杂的表达式 慎用watch ...

  8. (转)Webpack2 + Vue2 + Vue-Router2 如何实现懒加载?

    webpack2 的中 System.import 方法将被弃用, 推荐改成以下写法: https://www.mmxiaowu.com/article/5848239bd4352863efb5546 ...

  9. js插件---图片懒加载echo.js结合 Amaze UI ScrollSpy 使用

    js插件---图片懒加载echo.js结合 Amaze UI ScrollSpy 使用 一.总结 一句话总结:图片懒加载echo.js结合 Amaze UI ScrollSpy 使用的效果就是:懒加载 ...

随机推荐

  1. php中session_id()函数详细介绍,会话id生成过程及session id长度

    php中session_id()函数原型及说明session_id()函数说明:stringsession_id([string$id])session_id() 可以用来获取/设置 当前会话 ID. ...

  2. thinkphp--create()方法

    1.create方法可以对POST提交的数据进行处理(通过表中的字段名称与表单提交的名称对应关系自动封装数据实例),例如user表中有一个字段名叫"username",如果表单中有 ...

  3. koa+mysql实现增删改查-全栈之路(001)

    Date: 2020-4-23 以前很少写文章,从今天开始我要挑战一下自己,连续输出100篇技术类文章.这100篇文章我尽量以实战案例为主. 如果你觉得本文还不错,记得关注或者给个 star,你们的赞 ...

  4. Prometheus+Grafana 监控 Docker

    cAdvisor (Container Advisor) :用于收集正在运行的容器资源使用和性能信息. https://github.com/google/cadvisor Prometheus(普罗 ...

  5. Linux网络服务第一章Linux网络基础设置

    1.笔记 systenctl restart network:重启网卡网络服务 bash:刷新主机名称 netstat:查看网络状态 route -n:不做地址解析 mii-tool eno16777 ...

  6. 【集群实战】NFS网络文件共享服务2-mount挂载(参数,优化)

    1. NFS客户端挂载深入 1.1 NFS客户端挂载参数说明 在NFS服务端,可以通过cat /var/lib/nfs/etab查看NFS服务器端配置参数的细节. 在NFS客户端,可以通过cat /p ...

  7. openlayers3中Overlay用法

    Overlay 从名字看,是覆盖图.覆盖物的意思,主要的用途就是在地图之上再覆盖一层,用以显示额外的可见元素,可见元素一般是 HTML 元素,利用 overlay,可以将可见元素放置到地图的任意位置, ...

  8. spark系列-4、spark序列化方案、GC对spark性能的影响

    一.spark的序列化 1.1.官网解释 http://spark.apache.org/docs/2.1.1/tuning.html#data-serialization 序列化在任何分布式应用程序 ...

  9. #Week3 Linear Regression with Multiple Variables

    一.Multiple Features 这节课主要引入了一些记号,假设现在有n个特征,那么: 为了便于用矩阵处理,令\(x_0=1\): 参数\(\theta\)是一个(n+1)*1维的向量,任一个训 ...

  10. 在Jetson TX2上安装OpenCV(3.4.0)

    参考文章:How to Install OpenCV (3.4.0) on Jetson TX2 与参考文章大部分都是相似的,如果不习惯看英文,可以看看我下面的描述 在我们使用python3进行编程时 ...