The original link
Follow up with Webpack configuration notes
The sub-contract strategy
Start the YARN Analyze script on the branch feature/optimize_webpack and the subcontracting policy is as follows:
First screen load comparison
Original first screen loading
Loading after Upgrade
Subcontracting optimization steps
Echarts only extracts the required packages
app\components\ECharts\component.js
import echarts from 'echarts/lib/echarts';
import 'echarts/lib/chart/bar';
import 'echarts/lib/chart/line';
import 'echarts/lib/chart/pie';
import 'echarts/lib/component/tooltip';
import 'echarts/lib/component/legendScroll';
Copy the code
Immutable points to the same copy, avoiding duplicate packaging of draft and ANTD
internals/webpack/webpack.base.babel.js
'immutable': path.resolve(process.cwd(), 'node_modules/immutable'),
Copy the code
Large module rewriting method
According to the road
The original route reference module is already in the form of import().then(), so I added the following policy to splitChunks in the Webpack
internals/webpack/webpack.prod.babel.js
splitChunks: {
chunks: 'all'.// Split files regardless of whether they are dynamically loaded or not. All packages are introduced when the page first loads
maxInitialRequests: 10.// Maximum number of initial requests
minSize: 0.// Default 30000, in order not to merge chunks
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/.name(module) {
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?) (/ / \ \ | $) /,)1];
return `npm.${packageName.replace(The '@'.' ')}`; // Extract each third-party component, only when needed}},}},Copy the code
As you experiment, you can see that each page loads only the required packages
By component
React-player /draft/echarts is used for lazy loading of large components
One of the big problems is that lazy loading components cannot reference ref. After many experiments, the writing method is changed as follows
import React from 'react'; import Loadable from 'react-loadable'; const LoaderCache = new Map(); export default function loadComponent(loader, options) { let component = LoaderCache.get(loader); if (! component) { component = Loadable({ loader, loading: (props) => { if (props.error) {// eslint-disable-line console.error('[chunk loader]', props.error); // eslint-disable-line } return <div />; }, render: (loaded, props) => { const Component = loaded.default; const { withRef, ... rest } = props; // eslint-disable-line return (<Component ref={(r) => { withRef && withRef(r); }} {... rest} />); },... options, }); LoaderCache.set(loader, component); // component.preload(); } return component; }Copy the code
Usage:
app\components\GraphHintTextArea\index.js
import loadComponent from 'utils/loader';
export default loadComponent(() = > import(/* webpackChunkName: "c-graph-hint-text-area" */'./component'), null);
Copy the code
<GraphHintTextArea
withRef={(r) = > { this.graphHintTextArea = r; }} / >Copy the code
Antd only loads the ICONS needed
internals/webpack/webpack.base.babel.js
'@ant-design/icons/lib/dist$': path.resolve('app/icons'),
Copy the code
app/icons/index.js
// fill
export {
default as ExclamationCircleFill,
} from '@ant-design/icons/lib/fill/ExclamationCircleFill';
// outline
export {
default as QuestionCircleOutline,
} from '@ant-design/icons/lib/outline/QuestionCircleOutline';
// twotone
export {
default as ProfileTwoTone,
} from '@ant-design/icons/lib/twotone/ProfileTwoTone';
Copy the code