阅读 79

React 性能优化之组件动态加载(react-loadable)

  • React 项目打包时,如果不进行异步组件的处理,那么所有页面所需要的 js 都在同一文件中(bundle.js),整个js文件很大,从而导致首屏加载时间过长。

  • 所有,可以对组件进行异步加载处理,通常可以使用 React-loadable

React-loadable 使用

例如,对于项目中的detail组件(/src/pages/detail/),在 detail 目录下新建 loadable.js:

import React from 'react';
import Loadable from 'react-loadable'; 
const LoadableComponent = Loadable({ 
    loader: () => import('./index.js'),
    loading() {
        return <div>正在加载</div> 
    },
 }); 
  export default () => <LoadableComponent/>复制代码

然后在 app.js 里面引入detail组件:

// 不适用 react-loadable 时的引入方式:
// import Detail from './pages/detail/index';
// 使用 react-loadable 时的引入方式:
import Detail from './pages/detail/loadable';

... ... 

class App extends Component {
  render() {
    return (
      <Provider store={store}>
        <Fragment>
          <BrowserRouter>
            ··· ···
            <Route path='/detail/:id' exact component={Detail}></Route>
            ··· ···
          </BrowserRouter>
        </Fragment>
      </Provider>
    )
  }
}复制代码

但是,在/pages/detail/index.js文件中,如果想访问到当前路由的 match,location,history对象,就访问不到了

需要使用 withRouter 对 /detail/index.js 作如下处理:

class Detail extends Component {
  render() {
        ··· ···
  }

  componentDidMount() {
    // withRouter处理后,就可以在这里拿到 match 对象了
    console.log(this.props.match);
    this.props.getDetail(this.props.match.params.id);
  }
}
 
··· ···

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Detail));复制代码

withRouter 可以将一个非路由组件包裹为路由组件,使这个非路由组件也能访问到当前路由的match, location, history对象。

统一处理

上面已经实现了动态加载 detail 组件的方式,但是如果有多个组件时,需要在每个组件下新建 loadable.js ,比较麻烦,所有可以统一封装处理所有组件的动态加载。

新建目录/src/utils,新建文件 /src/utils/loadable.js

export default (loader) => {
  return Loadable({
    loader,
    loading() {
      return <div>正在加载</div>
    },
  });
}复制代码

在 app.js 中,

import { withRouter } from 'react-router-dom';

import React from 'react';
import Loadable from 'react-loadable';

import loadable from './utils/loadable';
import Header from './common/header'; 

< !--异步加载组件-->
const Home = loadable(() => import('./pages/home'));
const Detail = loadable(() => import('./pages/detail'));
const Login = loadable(() => import('./pages/login'));
const Write = loadable(() => import('./pages/write'));

class App extends Component {

  render() {
    return (
      <Provider store={store}>
        <Fragment>
          <BrowserRouter>
            <div>
              <Header />
              <Switch>
                <Route
                  exact
                  path="/"
                  render={() => <Redirect to="/home" />}
                />
                <Route path='/home' exact component={Home}></Route>
                <Route path='/login' exact component={Login}></Route>
                <Route path='/write' exact component={Write}></Route>
                <Route path='/detail/:id' exact component={Detail}></Route>
                <Route render={() => <div>Not Found</div>} />
              </Switch>
            </div>
          </BrowserRouter>
        </Fragment>
      </Provider>
    )
  }
}

export default App;


作者:MK麦客
链接:https://juejin.cn/post/7028743907303227423


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐