Asynchronous Component Loading Based on Create React App Routing 4.0
This article is an additional chapter that can help speed up the initial component loading time in your React app. Of course, this is not entirely necessary, but if you're curious, follow this article to help react.js build large applications with the asynchronous loading of Create React App and react Routing 4.0.
Code Splitting
When we write our one-page application with react.js, the application will become larger and larger. An application (or routing page) may introduce a large number of components, but some components are unnecessary when they are first loaded. These unnecessary components will waste a lot of loading time.
You may notice that Create React App generates a large. js file after packaging, which contains all the JavaScript that our application needs. However, if the user just loads the login page to login to the website, it doesn't make sense for us to load the rest of the application. This wasn't a problem when our application was very small, but it was one of our programming apes'optimizations. To solve this problem, Create React App has a very simple code segmentation scheme.
Code segmentation and react-router
In our react app, common routing configurations may look like the following
/* 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> );
We start by introducing these components, and then define the path that matches them according to our routing.
However, we import all the components in the route statically at the top. This means that no matter which route matches, all these components are loaded. We only load components that respond when we load matching routes. Next we will accomplish this mission step by step.
Create an asynchronous component
Create a JS file, such as src/components/AsyncComponent.js, with the following code
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; }
We have done something here:
This asyncComponent function accepts an importComponent parameter, which is dynamically introduced into a given component when called.
In componentDidMount, we simply call the importComponent function and save the dynamically loaded components in state.
Finally, if rendering is complete, we can provide components conditionally. Here, if we don't write null, we can also provide a chrysanthemum diagram, which represents the component being rendered.
Using asynchronous components
Now let's use our asynchronous components instead of introducing them as static at the beginning.
import Home from './containers/Home';
We use asyncComponent components to dynamically introduce the components we need.
tip: Don't forget to import asyncComponent from'. / AsyncComponent first
const AsyncHome = asyncComponent(() => import('./containers/Home'));
We're going to use the AsyncHome component in our routing
<Route path="/" exact component={AsyncHome} />
Now let's get back to it. Notes project And apply these changes.
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 }) => ( <Switch> <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} /> </Switch> );
It's pretty cool to make a few changes. Our app s all have code splitting. Nor does it add much complexity.
Here we look at the previous src/Routes.js routing file
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 }) => ( <Switch> <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} /> { /* Finally, catch all unmatched routes */ } <Route component={NotFound} /> </Switch> );
Note that don't introduce all the components at the top. We are creating these code splitting capabilities to dynamically import for us when necessary.
Now you run npm run build and you will see that the code has been split into a small file.
Here's a real screenshot of the deployed site
Every. chunk.js is loaded when needed. Of course, our program is quite small, and separate parts of the small components, do not need to load on demand like this. It depends on the needs of your project.
Original address: http://serverless-stack.com/c...