Use React Lazy for code splitting
As things stand we use a standard React import pattern when we need to utilize
exported components in other source files. One such example of this scenario occurs when
we use routes to dynamically determine what content to present our users with, such as in
scenes/office/index.jsx
or scenes/MyMove/index.jsx
.
Example using current method
import EditContactInfo from 'scenes/Review/EditContactInfo';
...
<Switch>
...
<ValidatedPrivateRoute exact path="/moves/review/edit-contact-info" component={EditContactInfo} />
...
</Switch>
Considered Alternatives
- Leave things as they are
- Use React Loadable
- Use Loadable Components
- Use React Lazy
Decision Outcome
- Chosen Alternative: Use React Lazy
This option allows us to ensure we are only loading what's required into the users browser for components as they are first rendered. The technique can be effectively implemented in places where routes as used to dynamically decide what component to offer the customer. Introducing this into those places allows us to gain performance benefit without the introduction of significant complexity.
While React Loadable has been implemented in the project before, such as in src/App/index.js
, it is no longer actively
supported, which is why utilizing an alternative like React Lazy is preferable.
Using this specific tool allows us to make use of the pattern in a way that should be compatible for upcoming performance focused React features that we may find desirous to use in the future.
Example using React Lazy
...
const DocumentViewer = lazy(() => import('./DocumentViewer'));
...
<Switch>
...
<Suspense fallback={<LoadingPlaceholder />}>
<RenderWithOrWithoutHeader
component={DocumentViewer}
withHeader={false}
tag={DivOrMainTag}
{...props}
/>
</Suspense>
...
</Switch>
In this example we use Lazy()
combined with import()
to bring in our needed component. This combination is what
allows us to ensure that it isn't presented to the browser until first render, which in this case should be when the
customer navigates to this route. The Suspense
tag provides an alternative thing to render while our content loads.
Pros and Cons of the Alternatives
Leave things as they are
+
No changes needed to be done.-
No improvement in front end performance
Use React Loadable
+
Performance improvement for frontend app-
Risk introduced due to library no longer being maintained-
Increase in verbosity for frontend routes
Use Loadable Components
+
Performance improvement for frontend app+
React team recommends this library for some use cases (server side rendering)-
Increase in verbosity for frontend routes-
Abstraction layer on top of a relatively new React features. Unknown how this might interact with development by React team on Concurrent Mode, which we may want to use in the future.
Use React Lazy
+
Performance improvement for frontend app+
Developed by React Team+
Designed to eventually interact with Concurrent Mode.-
Increase in verbosity for frontend routes