提升首屏加载时间原理:把大体积的包,分成多个小体积的包进行加载,减少请求时间
chainWebpack配置
在 umi.js 或者 umi.ts 或者 .umirc.js 或者 config.js 中配置,使用 webpack 的优化模块optimization.splitChunks实现。
chunks配置
chunks 配置需要加上 umi,否则打包完后依旧是白屏,在控制台可看到 umi.js 和 umi.css 并没有引入。
compression-webpack-plugin服务端使用gzip进行压缩
打开 config/config.ts
文件(如果是 umi2 的项目则是 .umirc.js
)
import { defineConfig } from 'umi';
import { join } from 'path';
import defaultSettings from './defaultSettings';
import proxy from './proxy';
import routers from './routes';
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const prodGzipList = ['js', 'css'];
const { REACT_APP_ENV } = process.env;
export default defineConfig({
hash: true,
history: { type: 'hash' },
publicPath: './',
antd: {},
dva: {
hmr: true,
},
layout: {
// https://umijs.org/zh-CN/plugins/plugin-layout
locale: true,
siderWidth: 208,
...defaultSettings,
},
// https://umijs.org/zh-CN/plugins/plugin-locale
locale: {
// default zh-CN
default: 'zh-CN',
antd: true,
// default true, when it is true, will use `navigator.language` overwrite default
baseNavigator: true,
},
dynamicImport: {
loading: '@ant-design/pro-layout/es/PageLoading',
},
targets: {
ie: 11,
},
routes: routers,
// Theme for antd: https://ant.design/docs/react/customize-theme-cn
theme: {
'primary-color': defaultSettings.primaryColor,
},
// esbuild is father build tools
// https://umijs.org/plugins/plugin-esbuild
esbuild: {},
title: false,
ignoreMomentLocale: true,
proxy: proxy[REACT_APP_ENV || 'dev'],
manifest: {
basePath: '/',
},
// Fast Refresh 热更新
fastRefresh: {},
openAPI: [
{
requestLibPath: "import { request } from 'umi'",
// 或者使用在线的版本
// schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"
schemaPath: join(__dirname, 'oneapi.json'),
mock: false,
},
{
requestLibPath: "import { request } from 'umi'",
schemaPath: 'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json',
projectName: 'swagger',
},
],
nodeModulesTransform: { type: 'none' },
mfsu: {},
webpack5: {},
exportStatic: {},
chunks: ['vendors', 'umi'],
chainWebpack: (config) => {
config
.plugin('replace')
.use(require('webpack').ContextReplacementPlugin)
.tap(() => {
return [/moment[/\\]locale$/, /zh-cn/];
});
config.merge({
optimization: {
minimize: true,
splitChunks: {
chunks: 'async',
minSize: 30000,
minChunks: 2,
automaticNameDelimiter: '.',
cacheGroups: {
react: {
name: 'react',
priority: 20,
test: /[\\/]node_modules[\\/](react|react-dom|react-dom-router)[\\/]/,
},
echarts: {
name: 'echarts',
chunks: 'async',
test: /[\\/]node_modules[\\/](echarts|zrender)[\\/]/,
priority: 10,
enforce: true,
},
antdesigns: {
name: 'antdesigns',
chunks: 'all',
test: /[\\/]node_modules[\\/](antd|@ant-design|antd-mobile)/,
priority: 10,
enforce: true,
},
antv: {
name: 'antv',
chunks: 'all',
test: /[\\/]node_modules[\\/](@antv)[\\/]/,
priority: 10,
enforce: true,
},
lodash: {
name: 'lodash',
test: /[\\/]node_modules[\\/]lodash[\\/]/,
priority: -2,
enforce: true,
},
vendors: {
name: 'vendors',
test({ resource }: any) {
return /[\\/]node_modules[\\/]/.test(resource)
},
priority: -11,
enforce: true,
},
},
},
},
});
if (process.env.NODE_ENV === 'production') { // 生产模式开启
config.plugin('compression-webpack-plugin').use(
new CompressionWebpackPlugin({
algorithm: 'gzip',
test: new RegExp('\\.(' + prodGzipList.join('|') + ')$'),
threshold: 10240,
minRatio: 0.6,
deleteOriginalAssets: false, // 不删除源文件
})
);
}
},
});