此场景在项目中遇见,一看文档,二看 umi 开发社区中的大佬的优化,三结合自己以前的 webpack 配置经验总结而出。
为防止文档链接失效,笔者准备有些必要时候能抄就抄,保存文章整体性。
注意:此项目主要是笔者的经验之谈以及代码大小优化部分。
介绍完毕,准备开干:
查看包结构
首先,要查看代码尺寸,最直观的方式是 build
它,查看生成文件大小,不过 umi
中自带了查看包大小的 webpack
插件 analyze
,所以我们需要在 package.json
中配置 script
脚本:
1 2 3 4 5 6
| { "script": { "analyze": "cross-env ANALYZE=1 umi dev", "build:analyze": "cross-env ANALYZE=1 umi build" } }
|
执行 umi dev
或 umi build
时,增加环境变量ANALYZE=1
可查看产物的依赖占比
配置 externals
这个在 webpack 中常用到,就是比如基本库,可以通过 externals 的配置引入相关的 umd 文件,减少编译消耗
比如 react 和 react-dom:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| export default { externals: { react: 'window.React', 'react-dom': 'window.ReactDOM', }, scripts: process.env.NODE_ENV === 'development' ? [ 'https://gw.alipayobjects.com/os/lib/react/16.8.6/umd/react.development.js', 'https://gw.alipayobjects.com/os/lib/react-dom/16.8.6/umd/react-dom.development.js', ] : [ 'https://gw.alipayobjects.com/os/lib/react/16.8.6/umd/react.production.min.js', 'https://gw.alipayobjects.com/os/lib/react-dom/16.8.6/umd/react-dom.production.min.js', ], }
|
减少补丁尺寸
因为本项目为移动端项目,所以这块的配置如下
1 2 3 4 5 6 7
| targets: { chrome: 49, firefox: 45, safari: 10, edge: 13, ios: 10, },
|
调整 splitChunks 策略,减少整体尺寸
做一块的前提是将dynamicImport(按需加载)
,在没开启按需加载前,umi 只会生成一个 js 和一个 css,即 umi.js
和 umi.css
。优点是省心,部署方便,缺点是对用户来说初次打开网站会比较慢。这显然是要优化的,因为前端优化中按需加载是肯定要做的,具体如何做可以查看 UmiJS 的官网,这里不做描述。
但如果开了 dynamicImport,产物特别大,每个出口文件都包含了相同的依赖,比如 自己的 UI 库,可尝试通过 splitChunks 配置调整公共依赖的提取策略
比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| export default { chunks: ['vendors', 'umi'], chainWebpack: function (config, { webpack }) { config.merge({ optimization: { splitChunks: { chunks: 'all', minSize: 30000, minChunks: 3, automaticNameDelimiter: '.', cacheGroups: { vendor: { name: 'vendors', test({ resource }) { return /[\\/]node_modules[\\/]/.test(resource) }, priority: 10, }, }, }, }, }) }, }
|
图片资源压缩
UI 提供图片素材后,可通过 TinyPNG(https://tinypng.com/) 或者 pngquant 等网站对图片经验进一步压缩
选用可替代的依赖库
大的依赖包能换就换,例如 monent 库比较大,我们可以替换成 dayjs,或者如果只用到其中的几个方法(例如 lodash 中的防抖节流)完成可以自己写
开启 gzip 压缩
下载 webpack 插件
1
| npm i compression-webpack-plugin @types/compression-webpack-plugin --save
|
进入 umi 的配置文件中,引入并配置 gzip 压缩
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import CompressionPlugin from 'compression-webpack-plugin'; import { defineConfig } from 'umi'; const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
export default defineConfig({ ... chainWebpack(memo: any, args: any) { memo.plugin('CompressionPlugin').use( new CompressionPlugin({ filename: '[path].gz[query]', algorithm: 'gzip', test: productionGzipExtensions, threshold: 10240, minRatio: 0.8, deleteOriginalAssets: false, }), ); }, })
|
以上就是 umi 项目的优化方案。
经过压缩后,30 个页面的代码从没优化前的 3M 代码,压缩到 2.5M(含 gzip),虽然压缩大小没怎么变化,但是用户体验有了质的飞跃。
配合 nginx 的 gzip 压缩以及缓存策略,更能加快页面访问
参考资料