Dynamic imports
Lazy-loading in a nutshell
This article is a brief description on how to use dynamic imports in javascript to reduce wasteful network traffic. This method results in only downloading necessary code when necessary. If you need to reduce the amount of data you download, and you are using a large website with many different features, but you only want one feature, then you should only download information for that one feature; you should not download all the information for the other features. This would be wasteful. In order to avoid this, the website must be set up to load modules of code "lazily", that is only when requested. A developer must organise the code efficiently between different files, and organise these files so that features can be downloaded on demand. Lazy Loading is not a new concept, however it is extremely useful and extremely easy to understand.
The ability to load features on demand.
import(pathToFile).then(e => {
console.log("module loaded!");
});
Modules and Webpack
Webpack is a module bundler, which bundles javascript modules into concise files for serving to clients. It is used during the build phase of multiple frameworks including Create React App, NextJS, and Angular. This allows developers to use the import
and export
statements of ES6 to separate Javascript across files during development. These statements are a consideration when preparing a website for Lazy Loading.
import CustomFeature from “path-to-file”;
Do it with React
React provides the Component class, which is used to return JSX to render in DOM. This class introduces the concept of a Lifecycle and internal state. The Lifecycle exposes ‘lifecycle hooks’, which allow developers to insert custom behaviour into the React Component while it mounts and unmounts html. The internal state state allows sharing of information between these states. The Lifecycle and Internal State are distinctive aspects of the React Component and are instrumental in implementing lazy-loading.
To implement dynamic imports in react could look like this:
import React from "react";
class LazilyLoadedCustomFeature extends Component {
state = {
content: null
};
componentDidMount() {
import(pathToFile).then(e => {
this.setState({ content: e });
});
}
render() {
const { content } = this.state;
return content;
}
}
export default LazilyLoadedCustomFeature;
Do it with Next.js
import React from "react";
import dynamic from "next/dynamic";
const DynamicComponentWithNoSSR = dynamic(
() => import("../components/threejs/scene"),
{
ssr: false
}
);
class Three extends React.Component {
render() {
return (
<div>
<DynamicComponentWithNoSSR />
</div>
);
}
}
export default Three;
Summary
Without the static import statement at the top of the file, the module is not bundled with the rest of the app. It is bundled in its own file and it can be dynamically imported through the call to import(“path-to-file”)
.
The general approach illustrated in the above figure can be reused many times; constituting a design pattern. As such, there is already open source solutions for it. One very popular open source package for this is react-loadable. The Loadable component provided by react-loadable is perfectly sufficient for implementing Lazy Loading within a framework such as Create React App. If you are using a more full-featured framework such as NextJS or Angular, they tend to have their own preconfigured recommendation for how to do this.