dynamic import不知道为何有不少叫法,什么按需加载,懒加载,Code Splitting,代码分页等。 总之,就是在SPA,把JS代码分红N个页面份数的文件,不在用户刚进来就所有引入,而是等用户跳转路由的时候,再加载对应的JS文件。 这样作的好处就是加速首屏显示速度,同时也减小了资源的浪费。html
GitHub项目地址react
这个一个完整的项目,这节相关的内容可在router/routerMap.jsx中找到。webpack
babel用的是babel-env,使用方法能够去babel官方学习,实践可看我项目的源代码。git
npm i -D babel-plugin-syntax-dynamic-import
之后, 在.babelrc文件的plungins中加上"syntax-dynamic-import"
。github
npm i -S react-loadable
之后,咱们就能愉快得作dynamic import了。web
import React from 'react';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import createHistory from 'history/createBrowserHistory';
const history = createHistory();
import App from 'containers';
// 按路由拆分代码
import Loadable from 'react-loadable';
const MyLoadingComponent = ({ isLoading, error }) => {
// Handle the loading state
if (isLoading) {
return <div>Loading...</div>;
}
// Handle the error state
else if (error) {
return <div>Sorry, there was a problem loading the page.</div>;
}
else {
return null;
}
};
const AsyncHome = Loadable({
loader: () => import('../containers/Home'),
loading: MyLoadingComponent
});
const AsyncCity = Loadable({
loader: () => import('../containers/City'),
loading: MyLoadingComponent
});
const AsyncDetail = Loadable({
loader: () => import('../containers/Detail'),
loading: MyLoadingComponent
});
const AsyncSearch = Loadable({
loader: () => import('../containers/Search'),
loading: MyLoadingComponent
});
const AsyncUser = Loadable({
loader: () => import('../containers/User'),
loading: MyLoadingComponent
});
const AsyncNotFound = Loadable({
loader: () => import('../containers/404'),
loading: MyLoadingComponent
});
// 路由配置
class RouteMap extends React.Component {
render() {
return (
<Router history={history}>
<App>
<Switch>
<Route path="/" exact component={AsyncHome} />
<Route path="/city" component={AsyncCity} />
<Route path="/search/:category/:keywords?" component={AsyncSearch} />
<Route path="/detail/:id" component={AsyncDetail} />
<Route path="/user" component={AsyncUser} />
<Route path="/empty" component={null} key="empty" />
<Route component={AsyncNotFound} />
</Switch>
</App>
</Router>
);
// 说明
// empty Route
// https://github.com/ReactTraining/react-router/issues/1982 解决人:PFight
// 解决react-router v4改变查询参数并不会刷新或者说重载组件的问题
}
}
export default RouteMap;
复制代码
咱们能够运行webpack,而后就能看到效果(图仅为dev环境,build才会再打包一个vendor.js,为何要有vendor.js,请见devDependencies和dependencies的区别 >>)npm
Code Splitting in Create React Appsegmentfault
有同窗表示,个人方法作页面分离并无什么好处,由于每一个页面都依赖了三方库的代码,因此其实页面有不少冗余代码,能想到这点很棒,已经开始有架构思惟了。不过,注意这个想法在dev
环境下,这个同窗是对的。bash
那到了build
环境,或者说到了发布环境,又是怎么样的呢?的确,这篇文章我没有提到,请见个人另外一篇文章devDependencies和dependencies的区别。这篇文章主要解释了npm的package.json中devDependencies和dependencies区别是什么。
看完之后,咱们就能够知道,为何我以前说“注意这个想法在dev
环境下,这个同窗是对的”了。由于,咱们npm run build
之后,webpack会把三方包打包到vendor.js文件,页面逻辑代码不会牵涉其中,每一个页面都会引用vendor.js这个文件,这样的话,就不会出现重复引入冗余代码的状况了。