天天看點

【翻譯】基于 Create React App路由4.0的異步元件加載(Code Splitting)

基于 create react app路由4.0的異步元件加載

本文章是一個額外的篇章,它可以在你的react

app中,幫助加快初始的加載元件時間。當然這個操作不是完全必要的,但如果你好奇的話,請随意跟随這篇文章一起用create react app和

react路由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 () => ( 

  <switch> 

    <route path="/" exact component={home} /> 

    <route path="/posts/:id" exact component={posts} /> 

    <route component={notfound} /> 

  </switch> 

);  

我們一開始引入這些元件,然後定義好的路徑,會根據我們的路由去比對這些元件。

但是,我們靜态地在頂部導入路由中的所有元件。這意味着,不管哪個路由比對,所有這些元件都被加載。我們隻想加載對比對路由的時候才加載響應的元件。下面我們一步步來完成這個使命。

建立一個異步元件

建立一個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 

        ? <c {...this.props} /> 

        : null; 

  } 

  return asynccomponent; 

}  

我們在這裡做了一些事情:

這個asynccomponent 函數接受一個importcomponent 的參數,importcomponent 調用時候将動态引入給定的元件。

在componentdidmount 我們隻是簡單地調用importcomponent 函數,并将動态加載的元件儲存在狀态中。

最後,如果完成渲染,我們有條件地提供元件。在這裡我們如果不寫null的話,也可提供一個菊花圖,代表着元件正在渲染。

使用異步元件

現在讓我們使用我們的異步元件,而不是像開始的靜态去引入。

我們要用asynccomponent元件來動态引入我們需要的元件。

tip: 别忘記 先 import asynccomponent from './asynccomponent

const asynchome = asynccomponent(() => import('./containers/home')); 

我們将要使用 asynchome 這個元件在我們的路由裡面

<route path="/" exact component={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 }) => ( 

    <appliedroute path="/" exact component={asynchome} props={childprops} /> 

    <unauthenticatedroute path="/login" exact component={asynclogin} props={childprops} /> 

    <unauthenticatedroute path="/signup" exact component={asyncsignup} props={childprops} /> 

    <authenticatedroute path="/notes/new" exact component={asyncnewnote} props={childprops} /> 

    <authenticatedroute path="/notes/:id" exact component={asyncnotes} props={childprops} /> 

    { /* finally, catch all unmatched routes */ } 

    <route component={asyncnotfound} /> 

隻需幾次更改就相當酷了。我們的app都是設定了代碼分割而的。也沒有增加太多的複雜性。

這裡我們看看之前的這個src/routes.js路由檔案

import login from './containers/login'; 

import notes from './containers/notes'; 

import signup from './containers/signup'; 

import newnote from './containers/newnote'; 

    <appliedroute path="/" exact component={home} props={childprops} /> 

    <unauthenticatedroute path="/login" exact component={login} props={childprops} /> 

    <unauthenticatedroute path="/signup" exact component={signup} props={childprops} /> 

    <authenticatedroute path="/notes/new" exact component={newnote} props={childprops} /> 

    <authenticatedroute path="/notes/:id" exact component={notes} props={childprops} /> 

注意,不要在頂部的引入所有的元件。我們正在建立這些代碼分割的功能,以便在必要時為我們進行動态導入。

現在你運作npm run build 您将看到代碼已經被分割成一個個小檔案。

【翻譯】基于 Create React App路由4.0的異步元件加載(Code Splitting)

下面是部署好的在網站的真實截圖

【翻譯】基于 Create React App路由4.0的異步元件加載(Code Splitting)

每個.chunk.js都是需要的時候才加載的。當然我們的程式是相當小的,并且分離在各個部分的小元件,是不需要這樣子按需加載的。還是看你項目的需求。

作者:佚名

來源:51cto

繼續閱讀