team
team copied to clipboard
React-loadable 基于组件的代码拆分
React-loadable
使用背景
- 当你的项目足够大时,把所有代码打包到一个bundle中的启动时间会非常缓慢。这时就需要把app组件拆分为若干个bundle,按需加载。
异步加载的几种方式
一、基于webpack
的require.ensure实现code splitting
示例如下(PC略懂商城tab切换)
require.ensure(['./goldGuild'], (require) => {
let GoldGuild = require('./goldGuild').default;
ReactDOM.render(<GoldGuild/>, document.getElementById("container"));
});
二、基于路由
React-Router的按需加载(PC略懂发布)
示例如下
let App = () => {
let {HashRouter, Route, hashHistory} = ReactRouterDOM;
return <HashRouter history={hashHistory}>
<div id="routerContainer">
<Route path="/" component={null}/>
<Route path="/question" component={WorldQuestionPop}/>
<Route path="/vote/select" component={SelectVoteType'}/>
<Route path="/vote/textVote" component={VoteTextPop}/>
<Route path="/vote/picVote" component={VotePop}/>
<Route path="/pk" component={WorldPkPopShow}/>
</div>
</HashRouter>
};
ReactDOM.render(App(), document.getElementById("container"));
三、基于组件
的 React-loadable(PC略懂话题广场tab切换和首屏渲染)
示例如下
import Loadable from 'react-loadable';
import TopicPlaceholder from './topicPlaceholder';
let LoadableExample = Loadable({
// topicFeedList是需要异步加载的组件
loader: () => import('./topicFeedList'),
// loading 为异步加载之前的占位loading
loading: () => {
// loading: () => null, 可以将loading设置为空
return <TopicPlaceholder length="5"/>
},
delay: 300, // 防止loading一闪而过
});
export default class ReactLoadable extends React.Component {
render() {
return (
<div>
<LoadableExample/>
</div>
);
}
}
ReactDOM.render(<ReactLoadable/>, document.getElementById("container"));
-
Loadable 是一个高阶组件(创建组件的function)用来轻易地在
组件层面
拆分bundle。Loadable的用法很简单。你仅仅要做的就是把要加载的组件和当你加载组件时的“Loading”组件传入一个方法中
示例中的loader和loading。 -
避免组件加载闪烁:有时组件加载非常快(<200ms),这时加载中的样式就会一闪而过。有大量用户研究表明,这样会让用户感觉到比实际加载更长的等待时间,给Loadable传入第三个参数用来自定义这个值,你的Loading组件只在加载时间比设定delay时间长时才会显示。
-
预加载:可以在组件渲染之前对它进行预加载。举个例子,当你需要在点击按钮时加载一个新组件,可能需要用户hover在按钮上时就预加载它。
let LoadableMyComponent = Loadable(
() => import('./another-component'),
loading: () => return <MyLoadingComponent/>,
);
class MyComponent extends React.Component {
state = { showComponent: false };
onClick = () => {
this.setState({ showComponent: true });
};
onMouseOver = () => {
LoadableMyComponent.preload(); // 预加载的静态方法
};
render() {
return (
<div>
<button onClick={this.onClick} onMouseOver={this.onMouseOver}>
Show loadable component
</button>
{this.state.showComponent && <LoadableMyComponent/>}
</div>
)
}
}