本文讲解的是最近在做的一个多页面项目,结合webpack4的splitChunks进行代码包分拆的过程
项目框架
项目有home和topic两个入口文件,主要包括:
- react、mobx、antd作为项目的基本框架,
- echarts和d3(画图)是项目中部分页面用到比较大的组件库
- src下的工作的组件和代码
- 其他的非公共代码。
两个入口文件都用react-loadable做了异步加载
import Loadable from 'react-loadable'; ... const LoadableLogin = Loadable({ loader: () => import('../../common/components/login'), loading: Loading, }); ...
webpack部分配置相关如下:
module.exports = { ... mode: 'production', entry: { // 多入口 home: './src/home', topic: './src/topic', }, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' "~"那么,最终生成的就是 vendor~a~b.jsmaxInitialRequests 入口点处的最大并行请求数,默认为3
如果我们设置为1,那么每个入口文件就只会打包成为一个文件
maxAsyncRequests 最大异步请求数量,默认5
如果我们设置为1,那么每个入口文件就只会打包成为一个文件
优先级关系
maxInitialRequest / maxAsyncRequests <maxSize <minSize。
cacheGroups 定制分割包的规则
test可以配置正则和写入function作为打包规则。其他属性均可继承splitChunks,这里必须说一下 priority,设置包的打包优先级,非常重要! (后面结合实践)
minChunks
最少引入的次数
实践
我们以一个最简单的配置开始,将公共代码打包出来
splitChunks: { chunks: 'all', // initial、async和all minSize: 30000, // 形成一个新代码块最小的体积 maxAsyncRequests: 5, // 按需加载时候最大的并行请求数 maxInitialRequests: 3, // 最大初始化请求数 automaticNameDelimiter: '~', // 打包分割符 name: true, cacheGroups: { vendors: { // 打包两个页面的公共代码 minChunks: 2, // 引入两次及以上被打包 name: 'vendors', // 分离包的名字 chunks: 'all' }, } },两个入口文件的公共代码被打包到vendor文件夹下面,包括echarts d3 amcharts等一些三方包和src下的公共代码。
这当然不是我们想要的结果!存在以下问题:
- 其实当我们进入网站,一般第一步都是进入一个登陆页面,需要的只是项目的基本框架代码,例如react,react-dom.antd等,我们可以用all(或者initial)将它们单独打包,作为首页必须载入的包
- 我们打包的公共包,首次加载页面的时候,只想把同步加载的加载进来,所以需要一个同步的Common包
- 像echarts,d3,以及一些src下面一些异步加载的包,将它们利用async将打包成一个独立异步加载包
我们修改cacheGroups为:
cacheGroups: { vendors: { // 项目基本框架等 chunks: 'all', test: /(react|react-dom|react-dom-router|babel-polyfill|mobx)/, priority: 100, name: 'vendors', }, 'async-commons': { // 异步加载公共包、组件等 chunks: 'async', minChunks: 2, name: 'async-commons', priority: 90, }, commons: { // 其他同步加载公共包 chunks: 'all', minChunks: 2, name: 'commons', priority: 80, }, }
这次webpack帮我们打出来的包主要有:
- async-common:是两个入口文件都异步加载的三方包和利用react-loader做的懒加载代码,有echarts,d3等
- vendors: 包括react,react-dom,antd等
- commons: 引用超过两次的同步代码
这里说两个需要注意的地方:
- 注意这里我们priority的设置,vendors>async-commons>commons,我们首先将react,react-dom等优先打包出来,然后再打包公共部分,如果将vendors的优先级设置小于两个Common的优先级,那么react,react-dom将会打包到common包,将不会再生成vendors包。
- 如果我们这里将commons的配置去掉,将会生成一个topic~home的包,我们配置了async-common提取出异步加载的公共包后,将会默认将同步加载的公共包打包生成以automaticNameDelimiter连接符‘~'生成的名字'topic~home'包,内容其实和commons包内容完全一样,
ok!按照我们的要求,这样首次页面加载只会引入vendors,commons包,而不会引入async-common包,还是挺棒的!追求更精致的我们,再认真想想,是不是还可以做一些更好的优化?
到目前为止我们打包文件的打包是这样的:
用gzip压缩后,最大的async-common包有391kb。公司说最近因为一些状况,布置到生产后速度慢的时候,有时候只能有20kb/s的下载速度==。。。。于是继续split!
分析一下:
- async-common中包含了自己写的src组件和第三方组件
- async-common中比较大是echarts,zrender(echarts引入)和d3,结合项目来说,只有部分页面我们需要echarts(d3同),所以我们可以考虑将d3和echarts这两个比较大的包提取出来,等到某个页面需要的时候,再让其异步加载,这样就大大减小了async-common的体积了。
修改
cacheGroups: { vendors: { // 基本框架 chunks: 'all', test: /(react|react-dom|react-dom-router|babel-polyfill|mobx)/, priority: 100, name: 'vendors', }, d3Venodr: { // 将体积较大的d3单独提取包,指定页面需要的时候再异步加载 test: /d3/, priority: 100, // 设置高于async-commons,避免打包到async-common中 name: 'd3Venodr', chunks: 'async' }, echartsVenodr: { // 异步加载echarts包 test: /(echarts|zrender)/, priority: 100, // 高于async-commons优先级 name: 'echartsVenodr', chunks: 'async' }, 'async-commons': { // 其余异步加载包 chunks: 'async', minChunks: 2, name: 'async-commons', priority: 90, }, commons: { // 其余同步加载包 chunks: 'all', minChunks: 2, name: 'commons', priority: 80, }, }
当然,每次修改后,需要在htmlWebpackPlugin中配置chunk需要的包
plugins: [ new HtmlWebpackPlugin({ // home页面 filename: 'home.html', template: './template.html', chunks: ['vendors', 'commons', 'home'], }), new HtmlWebpackPlugin({ // topic页面 filename: 'topic.html', template: './template.html', chunks: ['vendors', 'commons', 'topic'], }), ],
后期还做了其他的拆分和优化,大概最大的包保持在100k左右,当然也不建议拆的特别小,因为浏览器http1可能一次性支持6次下载文件,太多可能会适得其反。大家可以根据自己的项目做不同的拆分方法,总而言之,就是为了让项目更完美的在线上运行,给用户更好的体验~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 中国武警男声合唱团《辉煌之声1天路》[DTS-WAV分轨]
- 紫薇《旧曲新韵》[320K/MP3][175.29MB]
- 紫薇《旧曲新韵》[FLAC/分轨][550.18MB]
- 周深《反深代词》[先听版][320K/MP3][72.71MB]
- 李佳薇.2024-会发光的【黑籁音乐】【FLAC分轨】
- 后弦.2012-很有爱【天浩盛世】【WAV+CUE】
- 林俊吉.2012-将你惜命命【美华】【WAV+CUE】
- 晓雅《分享》DTS-WAV
- 黑鸭子2008-飞歌[首版][WAV+CUE]
- 黄乙玲1989-水泼落地难收回[日本天龙版][WAV+CUE]
- 周深《反深代词》[先听版][FLAC/分轨][310.97MB]
- 姜育恒1984《什么时候·串起又散落》台湾复刻版[WAV+CUE][1G]
- 那英《如今》引进版[WAV+CUE][1G]
- 蔡幸娟.1991-真的让我爱你吗【飞碟】【WAV+CUE】
- 群星.2024-好团圆电视剧原声带【TME】【FLAC分轨】