前言
很久没有写分享了,期间一直在开发自己的小站,先已上线,更多功能在开发中,欢迎大家访问,如果打开是个美女,说明有点问题,我在整改,过段时间再来访问吧。传送门
下载站点-M1994.png
主题
问题
小站利用React
全家桶开发,在上线之后,发现第三方bundle
(2Mb左右)下载用了近20
秒。
最初发现的问题是nginx
压缩配置gzip
没有添加application/javascript
这个MIME
类型,但是仍然花了近5
秒。
解决过程
初始
起初,我的配置文件(webpack.dll.js
)内容如下:
const path = require('path');
const webpack = require('webpack');
const vendors = [
'react',
'antd',
'lodash'
... // 其他第三方库
]
const config = {
entry: { vendors },
output: {
filename: '[name].dll.js',
library: '[name]_library', // 与 DllPlugin 的 name 保持一致
},
plugins: [
new webpack.DllPlugin({
path: path.resolve('dll', '[name].manifest.json'),
name: '[name]_library', // 这里的命名要遵循变量命名规范,它是最终的包变量名
})
// prod 添加你的 Uglifyjs 插件
]
}
这个配置文件独立于你应用的
webpack.dev.js
或webpack.prod.js
等配置文件
PS:只附关键代码,项目根目录为project
,更多配置参数请参见官网
运行这个配置文件之后,这样会在/project/dll
目录中生成两个文件:
- vendors.dll.js
- vendors.manifest.json
我们需要在inedx.html
页面(也在项目根目录下)中将vendors.dll.js
引入
<script src="/dll/vendors.dll.js"></script>
在你的webpack.dev.js
或webpack.prod.js
配置的plugins
属性中添加:
const manifestFile = path.relove('dll, 'vendors.manifest.json'); // manifest.json 文件地址
const config = {
... // 其他配置
plugins: [
new webpack.DllReferencePlugin({
manifest: manifestFile
})
... // 其它 plugin
]
}
改进1
考虑到浏览器并发请求数默认为6
个,我开始拆分第三方包(webpack.dll.js
):
const Libs = {
ui: [
'antd'
],
base: [
'lodash'
],
frame: [
'react'
]
}
const config = {
entry: { ...Libs },
... // 其他配置
}
运行之后,会生成三个.js
和.manifest.json
文件,同样你需要将.js
引用加入到你的index.js
页面:
<script src="/dll/ui.dll.js"></script>
<script src="/dll/base.dll.js"></script>
<script src="/dll/frame.dll.js"></script>
而在你的webpack.dev.js
和webpack.prod.js
中,你需要多次调用DllReferencePlugin
插件:
const manifestFileUi = path.relove('dll, 'ui.manifest.json');
const manifestFileBase = path.relove('dll, 'base.manifest.json');
const manifestFileFrame = path.relove('dll, 'frame.manifest.json');
const config = {
... // 其他配置
plugins: [
new webpack.DllReferencePlugin({
manifest: manifestFileUi
}),
new webpack.DllReferencePlugin({
manifest: manifestFileBase
}),
new webpack.DllReferencePlugin({
manifest: manifestFileFrame
})
... // 其它 plugin
]
}
建议根据 Libs 变量写个函数循环生成
改进2
我发现antd
、lodash
打包出来仍然很大,那么就按需加载(webpack.dll.js
):
const Libs = {
ui: [
'antd/es/button',
'antd/es/input',
... // 其他你项目中用到的 UI 组件
],
base: [
'lodash/fp/get',
'lodash/fp/set',
... // 其他你项目中用到的函数
]
... // frame
}
最终的加载时间为1
秒左右
问题
lodash
按需加载的话,它使用方法改变如下:
// 之前
import _ from 'lodash';
_.get(...);
// 之后
import get from 'lodash/fp/get;
get(...)
但是第二种方法总是返回undefined
,所以我改回了第一种使用方法,但是仍然是按需打包,问题有待查找。
结束
先这么多,有问题欢迎留言。
网友评论