安利一波自己的小站,先已上线,更多功能在开发中,欢迎大家访问,如果打开是个美女,说明有点问题,我在整改。 传送门
小站利用 React 全家桶开发,在上线之后,发现第三方 bundle(2Mb 左右)下载用了近
秒。 最初发现的问题是 nginx 压缩配置 gzip 没有添加
- 20
这个 MIME 类型,但是仍然花了近
- application / javascript
秒。
- 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 目录中生成两个文件:
我们需要在 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
- ]
- }'
考虑到浏览器并发请求数默认为
个,我开始拆分第三方包(webpack.dll.js):
- 6
- 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 变量写个函数循环生成
我发现 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,所以我改回了第一种使用方法,但是仍然是按需打包,问题有待查找。
先这么多,有问题欢迎留言。
来源: https://juejin.im/post/5a4f031b518825733e6040c0