在引入动态路由前,我先引入一段同步代码,如下是我在业务中,同步的引入组件模块;
webpack code spliting。
import * as utils from '@/utils'
import Layout from '@/components/web/layout'
import Home from './home'
import Archives from './archives'
import Article from './article'
import List from './list'
import NotFount from '@/components/404'
import Categories from './categories'
/**
* @AsyncComponent {func} 实现动态加载路由(按需加载) dynamic router方法
*
*/
export default {
path: '/',
name: 'home',
component: Layout,
childRoutes: [
{ path: '', component: Home },
{ path: 'archives', component: Archives },
{ path: 'article/:id', component: Article },
{ path: 'categories', component: Categories },
{ path: 'categories/:name', component: List },
{ path: 'tags/:name', component: List },
{ path: '*', component: NotFount }
]
}
打包后,代码体积为
File sizes after gzip:
499.43 KB (+486.44 KB) build/static/js/1.458cd856.chunk.js
42.35 KB build/static/css/1.f02f7689.chunk.css
21.38 KB (+17.26 KB) build/static/js/main.72af566a.chunk.js
6.57 KB (+2.31 KB) build/static/css/main.cf03963b.chunk.css
719 B (-1.07 KB) build/static/js/runtime~main.229c360f.js
通过分析打包后的chunk,很臃肿,代码体积并没有达到预期的效果,这样一来我们页面的性能必定会受影响,影响首屏加载效率,因此,我们需要优化代码体积,保证在访问我们的系统的时候,只加载页面所需模块即可,这里使用的是import动态引入业务模块,来达到dynamic import
改造后代码
先定义一个HOC组件
// HOC AsyncComponent
import React from 'react'
const AsyncComponent = loadComponent => (
class AsyncComponent extends React.Component {
state = {
Component: null,
}
componentWillMount() {
if (this.hasLoadedComponent()) {
return;
}
loadComponent()
.then(module => module.default)
.then((Component) => {
this.setState({Component});
})
.catch((err) => {
console.error(`Cannot load component in <AsyncComponent />`);
throw err;
});
}
hasLoadedComponent() {
return this.state.Component !== null;
}
render() {
const {Component} = this.state;
return (Component) ? <Component {...this.props} /> : null;
}
}
);
export default AsyncComponent;
----------------------------------------------------------------------------
// router文件
export default {
path: '/',
name: 'home',
component: utils.AsyncComponent(() => import(/* webpackChunkName:'webLayout' */ '@/components/web/layout')),
// component: Layout,
childRoutes: [
{ path: '', component: utils.AsyncComponent(() => import(/* webpackChunkName:'home' */ './home')) }, // webpackChunkName 魔法注释,chunk文件输出文件名
{ path: 'archives', component: utils.AsyncComponent(() => import(/* webpackChunkName:'archives' */ './archives')) },
{ path: 'article/:id', component: utils.AsyncComponent(() => import(/* webpackChunkName:'article' */ './article')) },
{ path: 'categories', component: utils.AsyncComponent(() => import(/* webpackChunkName:'categories' */ './categories')) },
{ path: 'categories/:name', component: utils.AsyncComponent(() => import(/* webpackChunkName:'list1' */ './list')) },
{ path: 'tags/:name', component: utils.AsyncComponent(() => import(/* webpackChunkName:'list2' */ './list')) },
{ path: '*', component: utils.AsyncComponent(() => import(/* webpackChunkName:'404' */ '@/components/404')) }
]
}
----------------------------------------------------------------------------
// 打包输出
File sizes after gzip:
487.93 KB build/static/js/8.9f527408.chunk.js
39.55 KB build/static/css/8.079b0183.chunk.css
10.19 KB build/static/js/webLayout.7f7553ee.chunk.js
9.94 KB (-11.44 KB) build/static/js/main.439dfc0e.chunk.js
5.93 KB (-493.5 KB) build/static/js/1.66ac4a08.chunk.js
5.55 KB build/static/js/9.25b08965.chunk.js
4.77 KB (-1.8 KB) build/static/css/main.b66ed72b.chunk.css
3.97 KB build/static/js/article.a1beacba.chunk.js
2.86 KB build/static/js/list1.00732ca2.chunk.js
2.84 KB build/static/js/archives.f01ab942.chunk.js
1.85 KB build/static/css/webLayout.a2fe13d5.chunk.css
1.83 KB build/static/js/home.6ca77167.chunk.js
1.6 KB build/static/css/9.bb029f69.chunk.css
1.53 KB (+844 B) build/static/js/runtime~main.50aafd90.js
889 B (-41.48 KB) build/static/css/1.254111da.chunk.css
798 B build/static/css/list1.06967b68.chunk.css
743 B build/static/css/archives.6876953f.chunk.css
637 B build/static/css/article.32ba3967.chunk.css
554 B build/static/css/home.0bc3c792.chunk.css
530 B build/static/js/categories.05d3e4d8.chunk.js
189 B build/static/css/categories.ff662cf8.chunk.css
在引入dynamic-import之后,可以很清晰的看到,我们的代码被分割了多个文件,这样我们在请求页面资源的时候,可以提升性能;上面用到了Magic Comments,它的作用就是定义chunk的chunkName;