React 应用 Code Spliting 以及 懒加载

React 应用 Code Spliting 以及 懒加载

webpack是一个强大的框架,具有其它框架所不具备的Tree shaking,懒加载和代码分割的功能,今天主要来讲解React web开发中是如何与这些特性所结合的。
Code Spliting
关于代码分割,webpack官网是这样描述。
在这里插入图片描述
①入口起点:使用entry配置手动地分离代码。
这一部分可以参考上一篇博客MPA模式配置,采用多入口,多出口的打包方式,可将首次加载的代码减小。
②使用SplitChunksPlugin来减少重复的模块。
我们知道在React的项目中,很多页面都会重复的import react reac-dom等模块,如果在每一个页面中都打包一次,将会使每个页面体积都非常大,并且有重复的引用,这个SplitChunksPlugin就是将重复的部分提取成一个公共的部分,并且只引用一次的过程,官方推荐配置如下,在这里打包两个公共文件一个是vendors,里面是所有node_modules打包的结果,另外一个是自己编写的公共模块,如果重复的引用次数大于2,就将会被打包到公共的default模块中。

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 30000,
      minRemainingSize: 0,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 6,
      maxInitialRequests: 4,
      automaticNameDelimiter: '~',
      automaticNameMaxLength: 30,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
  }
};

③动态导入模块,实现代码的分割
这里利用动态导入的语法import()来实现代码分割,import()将会返回一个promise函数。webpack当遇到import()的时候就会把导入的模块进行单独的打包,首次加载的时候一并返回,这些模块一般是不会立即渲染,后续可能会因为某些不一定发生的需求才会被渲染。这种模式也被称为预加载。下面为一个预加载的例子,如下为一个信息检索的网站,首页渲染了信息的列表,这一部分被打包到main.js中,但是当不点击详情的情况下详情页内容是不渲染的,被打包到orgnization.js中,这里详情页分了八个主题,因此将分别生成八个不同的打包后的文件,目的是减少首屏显示的时间。
在这里插入图片描述
以社团详情举例子,首先新建一个asyncLoad.js文件。这一部分主要是处理异步导入的回调,异步导入成功后,在进行页面内容渲染。

import React, { Component } from 'react'
import { Icon } from 'antd'

export default load => (
    class ContentComponent extends Component {
        state = {
            com: null
        }
        componentDidMount() {
            load.then(mod => {
                return this.setState({ com: mod.default || mod })
            })
        }
        render() {
            if (this.state.com) {
                return (<this.state.com {...this.props} />)
            }
            return <Icon type="loading" />
        }
    }
)

在页面中使用如下

//首先将异步导入组件,传给asyncLoad 处理,返回一个待渲染组件
import asyncLoad from './asyncLoad';
const Component = import(/* webpackChunkName: 'orginzation' */'./Orgnization/OrgnizationClub');
const Orgnization = asyncLoad(Component);
//在render中渲染该组件
return (isLoading?<Spin/>:<Orgnization data={detailData.toJS()} />)

打包之后,加载首页
在这里插入图片描述
请求内容如下,可以看到他加载了main.js,vendors.js之后又加载了orgnization.js
在这里插入图片描述
在加载详情页就直接使用预加载的orgnization模块,这里就实现了用import()实现代码分割的一个预加载案例
懒加载
当首次加载时不需要去请求某些模块,而是真正发起请求的时候再去下载该模块,不请求就不去下载该模块,就叫做懒加载,在React16.6之前使用loadable-component插件。
①loadable-component
需要下载安装该模块,并在.babelrc中配置如下内容

{
  "presets": ["@babel/preset-react"],
  "plugins": ["@babel/plugin-syntax-dynamic-import"]
}

在这里以社团详情页为例子,使用方法如下,将OrgnizationClub社团详情组件用loadable包裹,在导出,在懒加载的地方引入该模块。

import loadable from "@loadable/component";
import React from 'react'

const OrgnizationClub = loadable(() => import("./OrgnizationClub.js"), {
  fallback: <div>正在加载</div>
});

export default (data) => <OrgnizationClub {...data}/>

点击首页
在这里插入图片描述
首页初次加载内容如下,加载了main.js和vendors.js
在这里插入图片描述
点击社团详情页
在这里插入图片描述
加载如下,除了请求了一些接口之外还请求了一个0.js文件,这个文件就是懒加载的社团详情文件,在需要加载的时候在进行请求并加载。
在这里插入图片描述
②利用React-lazy
要保证是React16.6版本以上,就可以用React.lazy实现懒加载,这里以懒加载社团详情为例子。使用React.lazy导入异步加载模块,并用Suspense组件包裹异步加载的组件。

const Orgnization = React.lazy(()=> import(/* webpackChunkName: 'orginzation' */'./Orgnization/OrgnizationClub'));

//在render中渲染的内容如下
<React.Suspense fallback={<div>Loading</div>}>
  <Orgnization data={detailData.toJS()} />
</React.Suspense>

在应用如上代码之后,点击首页,首页加载部分代码如下,只加载了main.js和vendors.js
在这里插入图片描述
点击社团详情,加载代码如下,又加载了一个orgnization.js模块
在这里插入图片描述

发布了38 篇原创文章 · 获赞 6 · 访问量 8568

猜你喜欢

转载自blog.csdn.net/qq_36400206/article/details/103260430