React中代码分割的4种实现方式

 更新时间:2022年01月25日 15:01:51   作者:紫圣  
虽然一直有做react相关的优化,按需加载、dll 分离、服务端渲染,但是从来没有从路由代码分割这一块入手过,所以下面这篇文章主要给大家介绍了关于React中代码分割的4种实现方式,需要的朋友可以参考下

前言

在 React 应用中,我们通常的做法是直接将某个模块导入到页面中,这样做导致的结果是打包出来的包体积过大。尤其是在引入了体积巨大的第三个库的情况下,打包后的包体积会十分巨大。因此,我们需要关注我们的应用中所包含的代码,以避免因体积过大而导致加载时间过长。

对代码进行分割能够“懒加载”当前用户所需要的内容,能够显著提高应用的性能。尽管并没有减少应用的整体代码体积,但可以避免加载用户永远不需要的代码,并在初始加载的时候可以减少所需加载的代码量。

下面,我们分别来介绍下在 React 中实现代码分割的几种方式。

import()

import() 是 Webpack 提供的用于分割代码的一个方法。该方法的返回结果是Promise,当文件加载完成后悔将模块导出给 promise.then 方法的回调。

例如有一个 math 模块,导出了 add方法和 minus 方法:

export const add = (a, b) => {
	return a + b;
}

export const minus = (a, b) => {
	return a - b;
}

通常的做法是在页面直接引入模块:

import { add } from './math'

console.log(add(5, 10));

使用 import 动态导入模块:

import('./math').then((math) => {
	console.log(math.add(5, 10))
})

当 Webpack 解析到该语法时,会自动进行代码分割。如果是使用 Create React App 创建的 React 应用,import 功能已开箱即用。

import React, { Component } from 'react';

class App extends Component {
  handleClick = () => {
    import('./math')
      .then(({ add }) => {
        add(5, 10)
      })
      .catch(err => {
        // Handle failure
      });
  };

  render() {
    return (
      <div>
        <button onClick={this.handleClick}>两数相加</button>
      </div>
    );
  }
}

export default App;

React.lazy

React.lazy 方法可以让我们动态加载组件,有助于缩减打包后 bundle 的体积,并延迟加载在初次渲染时未用到的组件。

React.lazy 接受一个函数,这个函数需要动态调用 import()。它必须返回一个 Promise,该 Promise 需要 resolve 一个 export default 的 React 组件。

const AsyncComponent = React.lazy(() => import('./OtherComponent'));

React.lazy 返回的是一个异步组件 不能单独使用,需要配合 React.Suspense 使用。当这个异步组件的状态是 pending 时显示的是 Suspense 中 fallback 的内容,只有 resolve 时才会显示加载好的组件。如此使得我们可以在使用 lazy 组件时做优雅降级(如在 fallback添加 loading 效果等)。

import React, { Suspense } from 'react';

const AsyncComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <AsyncComponent />
      </Suspense>
    </div>
  );
}

import() + React Loadable

React Loadable 是一个轻量级的代码分割组件,它是一个高阶组件,能让你的应用程序在渲染之前动态的加载任何模块。

使用 import() + React Loadable ,能优雅的实现基于 react-router 4.x 版本的路由分割:

import Loadable from 'react-loadable';

const LoadableBar = Loadable({
  loader: () => import('./components/Bar'),
  loading() {
    return <div>Loading...</div>
  }
});

class MyComponent extends React.Component {
  render() {
    return <LoadableBar/>;
  }
}

在实际业务开发中,我们通常会使用一些框架来快速开发React应用。在这些框架中,通常都会提供按需加载的功能。下面,我们来看看 UmiJS 框架中的按需加载。

UmiJS 按需加载

UmiJS 是一个可扩展的企业级前端应用框架,它以路由为基础,支持配置式路由和约定式路由。UmiJS 封装了一个 dynamic 组件来实现代码分割。

启用按需加载

UmiJS 的按需加载功能默认是关闭的,需要在使用之前通过配置开启。在 UmiJS 项目中添加如下的配置开启:

export default {
  dynamicImport: {},
}

使用按需加载

首先封装一个异步组件:

import { dynamic } from 'umi';
export default dynamic({
  loader: async function() {
    // 这里的注释 webpackChunkName 可以指导 webpack 将该组件 HugeA 以这个名字单独拆出去
    const { default: HugeA } = await import(/* webpackChunkName: "external_A" */ './HugeA');
    return HugeA;
  },
});

然后使用封装好的异步组件:

import React from 'react';
import AsyncHugeA from './AsyncHugeA';

export default () => {
  return <AsyncHugeA />;
}

总结

到此这篇关于React中代码分割的文章就介绍到这了,更多相关React代码分割内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React 实现爷孙组件间相互通信

    React 实现爷孙组件间相互通信

    这篇文章主要介绍了React实现爷孙组件间相互通信,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-08-08
  • React实现浮层组件的思路与方法详解

    React实现浮层组件的思路与方法详解

    React 浮层组件(也称为弹出组件或弹窗组件)通常是指在用户界面上浮动显示的组件,本文主要介绍了浮层组件的实现方法,感兴趣的小伙伴可以了解下
    2024-02-02
  • 用react实现一个简单的scrollView组件

    用react实现一个简单的scrollView组件

    这篇文章主要给大家介绍一下如何用 react 实现一个简单的 scrollView组件,文中有详细的代码示例,具有一定的参考价值,需要的朋友可以参考下
    2023-07-07
  • 深入掌握 react的 setState的工作机制

    深入掌握 react的 setState的工作机制

    本篇文章主要介绍了深入掌握 react的 setState的工作机制,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • React新文档切记不要滥用effect

    React新文档切记不要滥用effect

    这篇文章主要为大家介绍了React新文档滥用effect出现的问题详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • React中Suspense及lazy()懒加载及代码分割原理和使用方式

    React中Suspense及lazy()懒加载及代码分割原理和使用方式

    这篇文章主要介绍了React中Suspense及lazy()懒加载及代码分割原理和使用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-09-09
  • useReducer createContext代替Redux原理示例解析

    useReducer createContext代替Redux原理示例解析

    这篇文章主要为大家介绍了useReducer createContext代替Redux原理示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • react hooks入门详细教程

    react hooks入门详细教程

    这篇文章主要介绍了react hooks入门详细教程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • React父组件数据实时更新了,子组件没有更新的问题

    React父组件数据实时更新了,子组件没有更新的问题

    这篇文章主要介绍了React父组件数据实时更新了,子组件没有更新的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • 更强大的React 状态管理库Zustand使用详解

    更强大的React 状态管理库Zustand使用详解

    这篇文章主要为大家介绍了更强大的React 状态管理库Zustand使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10

最新评论