5.React 之 react-loadable

2,223 阅读3分钟

使用react-loadable实现代码分割

在开发react单页面应用时,我们会遇到一个问题,那就是打包后的js文件特别巨大,首屏加载会特别缓慢。这个时候我们应该讲代码进行分割,按需加载,将js 拆分成若干个chunk.js,用到就加载,react-loadable就可以很好地解决这个问题。

安装

yarn add react-loadable

基本使用

假设现在项目中有个 home页面组件src/pages/home/index.js

import React, { Component } from 'react'
class Home extends Component {
    render(){
        return (
            <div>这个是home页面</div>
        )
    }
}

export default Home

在没有使用react-loadable之前,在我们的route.js里面是直接import Home这个组件的,这时候,凡是直接import的组件都会直接打包到一个文件

import React, { Fragment } from 'react'
import { BrowserRouter, Route } from 'react-router-dom'

import Home from './pages/home'

const Routes = () => (
    <BrowserRouter>
        <Route path="/home" component={Home}/>
    </BrowserRouter>
);

export default Routes

在home文件下新建一个loadable.js文件src/pages/home/loadable.js

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

//通用的过场组件
const loadingComponent =()=>{
    return (
        <div>loading</div>
    ) 
}

export default Loadable({
    loader:import('./index.js'),
    loading:loadingComponent
});

然后再router里面调用

import React, { Fragment } from 'react'
import { BrowserRouter, Route } from 'react-router-dom'

import Home from '@pages/home/loadable'

const Routes = () => (
    <BrowserRouter>
        <Route path="/home" component={Home}/>
    </BrowserRouter>
);

export default Routes

因为只加载首页所需的依赖,所以体积会小很多,而且这个差距会随着项目的增大而变大

看代码,可以知道,工作原理其实就是在页面组件上有包了一成高级组件来代替原来的页面组件

到这里,代码分割其实已经解决了,但是如果项目有100个页面,那laodable.js就需要写100遍,这样就感觉太麻烦了,所以这个我们可以封装一下

我们在一个通用的位置新建一个loadable.js

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

//通用的过场组件
const loadingComponent = () => {
  return (
    <div>loading...</div>
  )
}

//过场组件默认采用通用的,若传入了loading,则采用传入的过场组件
export default (loader, loading = loadingComponent) => {
  return Loadable({
    loader,
    loading
  })
}

不难看出,我们可以将按需加载的组件和过渡组件通过参数传入最后返回包装后的组件,如此一来,home下面的laodable.js就不需要再建了

import React from 'react'
import Header from './components/Header'
import store from './store'
import { HashRouter, Route } from 'react-router-dom'
import loadable from './loadable'
import { Provider } from 'react-redux'
// 这种引用方便多了
const Home = loadable(() => import('./pages/home'))
const Login = loadable(() => import('./pages/login'))
const Detail = loadable(() => import('./pages/detail'))
const Write = loadable(() => import('./pages/write'))

function App() {
  return (
    <Provider store={store}>
      <HashRouter>
        <Header/>
        <div>
          <Route exact component={Home} path="/"/>
          <Route exact component={Login} path="/login"/>
          <Route exact component={Detail} path="/detail/:id"/>
          <Route exact component={Write} path="/write"/>
        </div>
      </HashRouter>
    </Provider>
  )
}

export default App

封装之后,laodable只需写一次,改变的只是组件的引入方式,这样一来就方便多了,react-loadable是以组件级别来分割代码的,这意味着,我们不仅可以根据路由按需加载,还可以根据组件按需加载,使用方式和路由分割一样,只用修改组件的引入方式即可

相关连接

最近在学习react开发,整理几篇笔记方便自己查询使用,下面是连接地址

1.React 之 react-transition-group

2.React之 redux、react-redux、redux-thunk

3.React 之 immutable 和 redux-immutable

4.React 之react-router-dom

5.React 之 react-loadable

6.React 基础记录

7.React 使用less等预处理器配置