team icon indicating copy to clipboard operation
team copied to clipboard

React-loadable 基于组件的代码拆分

Open MayOMengxuhui opened this issue 6 years ago • 0 comments

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>
    )
  }
}

MayOMengxuhui avatar Mar 15 '18 04:03 MayOMengxuhui