webpack 本地开发时, 经常会出现开发着然后打包速度很慢的情况. 酒店现在有大约 59 个页面, 这些页面都进行了惰性加载, 但是现在每个 chunk 打包出来的包很大 下面进行优化:
优化前先分析打包后的文件
可以看见每个 chunk 都很大 有些快达到了 1M.
使用 webpack-bundle-analyzer 分析输出文件, 如下图:
可以看出 lodash 被打包了很多次, 导致加载 lodash 的 chunk 很大.
下面编辑其中某一个 chunk, 并且保存, 如下图
重新打包时间达到了 2.592s, 其中起始文件 index.0a8ac.JS 达到了 841kb, 下面先优化各个 lodash 被加载很多次的问题.
lodash 等公共包优化
加入 webpack 异步公共打包配置
- new webpack.optimize.CommonsChunkPlugin({
- name: 'index',
- // the name or list of names must match the name or names
- // of the entry points that create the async chunks
- children: true,
- // (use all children of the chunk)
- async: true,
- // (create an async commons chunk)
- minChunks: 3,
- // 必须至少 3 个 chunk 里面包含该文件才进行公共打包 (3 children must share the module before it's separated)
- }),
下面再来看:
打包后的文件目录大小
可以看见减少了很多, 此时编辑重新打包发现大概只有 1094ms, 已经少了很多, 但是每次打包
出来的 index.hash.JS 还是很大, 体积并没有减少. 先看看结构
可以看见 moments 占用了很大体积, 但是明明 moment 已经被抽离为了公共包进行打包, 如下:
- Windows.__REACT_LIB={
- React:React,
- ReactDOM:ReactDOM,
- ReactRouter:ReactRouter,
- antd:antd,
- moment:moment,
- Backbone
- };
为什么还会打包? 该 index 文件是由入口文件包含路由 reducers 等以 router 进行分块之前的代码, 故现在从 App.JS 去查找, 发现如下代码:
- import moment from 'moment';
- import 'moment/locale/zh-cn';
- moment.locale('zh-cn');
虽然 webpack 打包配置里面有下面的
- externals:{
- 'react':'Windows.__REACT_LIB.React',
- 'react-dom':'Windows.__REACT_LIB.ReactDOM',
- 'react-router':'Windows.__REACT_LIB.ReactRouter',
- 'antd':'Windows.__REACT_LIB.antd',
- 'Backbone':'Windows.__REACT_LIB.Backbone',
- 'moment':'Windows.__REACT_LIB.moment',
- },
但是因为 import 'moment/locale/zh-cn'; 这行, moment 又被重新打包了, 现在去掉这行后. 现在看打包进度.
index 文件直接从 814 降到了 276kb. 优化完成 看打包文件:
编辑单个 chunk 后的重载
现在 chunk 里面还包含有 jQuery.JS, 这是因为 minChunk:3 设为 3 的缘故, 业务里面因为使用到了一个 jqeury.fancyTree.JS, 该模块会去加载 jQuery.JS
所以会这样. 现在去优化, 加入, 这样载入时便会之前去查找 Windows.$ 变量.
'jQuery':'Windows.$',, 现在, 整个优化完成.
来源: https://juejin.im/post/5ba4f2266fb9a05d28734815