资讯专栏INFORMATION COLUMN

【翻译】基于 Create React App路由4.0的异步组件加载(Code Splitting

fredshare / 2538人阅读

摘要:基于路由的异步组件加载本文章是一个额外的篇章,它可以在你的中,帮助加快初始的加载组件时间。但是,我们静态地在顶部导入路由中的所有组件。当然我们的程序是相当小的,并且分离在各个部分的小组件,是不需要这样子按需加载的。

基于 Create React App路由4.0的异步组件加载

本文章是一个额外的篇章,它可以在你的React app中,帮助加快初始的加载组件时间。当然这个操作不是完全必要的,但如果你好奇的话,请随意跟随这篇文章一起用Create React Appreact路由4.0的异步加载方式来帮助react.js构建大型应用。

代码分割(Code Splitting)

当我们用react.js写我们的单页应用程序时候,这个应用会变得越来越大,一个应用(或者路由页面)可能会引入大量的组件,可是有些组件是第一次加载的时候是不必要的,这些不必要的组件会浪费很多的加载时间。

你可能会注意到 Create React App 在打包完毕之后会生成一个很大的.js文件,这包含了我们应用程序需要的所有JavaScript。但是,如果用户只是加载登录页面去登录网站,我们加载应用程序的其余部分是没有意义的。在我们的应用程序还很小的时候,这并不是一个问题,但是它却是我们程序猿优化的一个东西。为了解决这个问题,Create React App有一个非常简单的代码分割的的方案。

代码分割和 react-router

在我们 react app 中,常见的路由配置可能是像下面一样的

/* Import the components */
import Home from "./containers/Home";
import Posts from "./containers/Posts";
import NotFound from "./containers/NotFound";


/* Use components to define routes */
export default () => (
  
    
    
    
  
);

我们一开始引入这些组件,然后定义好的路径,会根据我们的路由去匹配这些组件。

但是,我们静态地在顶部导入路由中的所有组件。这意味着,不管哪个路由匹配,所有这些组件都被加载。我们只想加载对匹配路由的时候才加载响应的组件。下面我们一步步来完成这个使命。

创建一个异步组件

创建一个js 文件,如:src/components/AsyncComponent.js,代码如下

import React, { Component } from "react";

export default function asyncComponent(importComponent) {
  class AsyncComponent extends Component {
    constructor(props) {
      super(props);

      this.state = {
        component: null
      };
    }

    async componentDidMount() {
      const { default: component } = await importComponent();

      this.setState({
        component: component
      });
    }

    render() {
      const C = this.state.component;

      return C ?  : null;
    }
  }

  return AsyncComponent;
}

我们在这里做了一些事情:

这个asyncComponent 函数接受一个importComponent 的参数,importComponent 调用时候将动态引入给定的组件。

componentDidMount 我们只是简单地调用importComponent 函数,并将动态加载的组件保存在状态中。

最后,如果完成渲染,我们有条件地提供组件。在这里我们如果不写null的话,也可提供一个菊花图,代表着组件正在渲染。

使用异步组件

现在让我们使用我们的异步组件,而不是像开始的静态去引入。

import Home from "./containers/Home";

我们要用asyncComponent组件来动态引入我们需要的组件。

tip: 别忘记 先 import asyncComponent from "./AsyncComponent

const AsyncHome = asyncComponent(() => import("./containers/Home"));

我们将要使用 AsyncHome 这个组件在我们的路由里面

现在让我们回到Notes项目并应用这些更改。

src/Routes.js

import React from "react";
import { Route, Switch } from "react-router-dom";
import asyncComponent from "./components/AsyncComponent";
import AppliedRoute from "./components/AppliedRoute";
import AuthenticatedRoute from "./components/AuthenticatedRoute";
import UnauthenticatedRoute from "./components/UnauthenticatedRoute";

const AsyncHome     = asyncComponent(() => import("./containers/Home"));
const AsyncLogin    = asyncComponent(() => import("./containers/Login"));
const AsyncNotes    = asyncComponent(() => import("./containers/Notes"));
const AsyncSignup   = asyncComponent(() => import("./containers/Signup"));
const AsyncNewNote  = asyncComponent(() => import("./containers/NewNote"));
const AsyncNotFound = asyncComponent(() => import("./containers/NotFound"));

export default ({ childProps }) => (
  
    
    
    
    
    
    { /* Finally, catch all unmatched routes */ }
    
  
);

只需几次更改就相当酷了。我们的app都是设置了代码分割而的。也没有增加太多的复杂性。
这里我们看看之前的这个src/Routes.js路由文件

import React from "react";
import { Route, Switch } from "react-router-dom";
import AppliedRoute from "./components/AppliedRoute";
import AuthenticatedRoute from "./components/AuthenticatedRoute";
import UnauthenticatedRoute from "./components/UnauthenticatedRoute";

import Home from "./containers/Home";
import Login from "./containers/Login";
import Notes from "./containers/Notes";
import Signup from "./containers/Signup";
import NewNote from "./containers/NewNote";
import NotFound from "./containers/NotFound";

export default ({ childProps }) => (
  
    
    
    
    
    
    { /* Finally, catch all unmatched routes */ }
    
  
);

注意,不要在顶部的引入所有的组件。我们正在创建这些代码分割的功能,以便在必要时为我们进行动态导入。

现在你运行npm run build 您将看到代码已经被分割成一个个小文件。

下面是部署好的在网站的真实截图

每个.chunk.js都是需要的时候才加载的。当然我们的程序是相当小的,并且分离在各个部分的小组件,是不需要这样子按需加载的。还是看你项目的需求。

原文地址:http://serverless-stack.com/c...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83857.html

相关文章

  • 2017-07-06 前端日报

    摘要:前端日报精选专题之类型判断下百度生态构建发布基于的解决方案将全面支持从绑定,看语言发展和框架设计掘金译机器学习与一付费问答上线,向你心目中的大牛提问吧产品技术日志中文第期团队技术信息流建设翻译基于路由的异步组件加载个必备的装逼 2017-07-06 前端日报 精选 JavaScript专题之类型判断(下) · Issue #30 · mqyqingfeng/Blog 百度Web生态构...

    shiguibiao 评论0 收藏0
  • Webpack 4.0 CommonsChunkPlugin 和 optimization spli

    摘要:可以通过配置属性进行修改,默认将会自动创建个库文件仅含有依然会创建个库文件仅含有假设所有的体积都大于将会创建一个库文件和一个通用组件文件仅含有当这些体积小于是,会故意将该模块复制到三个文件中。 该文章内容大致翻译自 webpack 4: Code Splitting, chunk graph and the splitChunks optimization 原有的问题 webpack...

    Caizhenhao 评论0 收藏0
  • 拒绝Redux文档“毒害” 一个项目告诉你Redux最新真正哲学

    摘要:之前分享过几篇关于技术栈的原创文章解析前端架构学习复杂场景数据设计干货总结打造单页应用一个项目理解最前沿技术栈真谛一个工程实例今天进一步剖析一个实际案例移动网页版。目前面临的问题在于提高产品的各方面性能体验。 之前分享过几篇关于React技术栈的原创文章: 解析Twitter前端架构 学习复杂场景数据设计 React Conf 2017 干货总结1: React + ES next ...

    YuboonaZhang 评论0 收藏0
  • The Cost Of JavaScript 2018 精读

    摘要:目前我们的业务项目采用的来进行优化和首屏性能提升。可变性需要让开发人员降低开发时的基准线,来保证每一个用户的体验。对于路由的切分以及库的引入来说,这一个原则至关重要。快速生成一份站点的性能审查报告。 The Cost Of JavaScript 2018 关于原文 原文是在Medium上面看到的,Chrome工程师Addy Osmani发布的一篇文章,这位的Medium上面的自我介绍里...

    lushan 评论0 收藏0

发表评论

0条评论

fredshare

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<