K
K
KBBS2019-03-28 16:05:52
JavaScript
KBBS, 2019-03-28 16:05:52

How do I use React.lazy? Or what are the alternatives?

Good afternoon.
It is assumed that the site will have some functionality that will be used very rarely.
This functionality is represented by React components.
I do not want to include it in the general bundle (in order to reduce the size of the bundle).
Ideally, it would be nice to do lazy loading on demand.
At the moment, there is a loader function that takes the URL where the script needs to be loaded and returns a promise.
In the right place, we call this function. And in then/catch we process the result (either we render the component, or we process the error.
In general, we have something like this:

function loadScript(url) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.async = true;
script.onload = resolve;
script.onerror = reject;
script.src = url;
document.body.appendChild(script);
});
}

Usage:
loadScript('/js/lazy-component.js')
.then( ... )
.catch( ... );

In principle, you can arrange everything a little differently. Approximately as described here: https://habr.com/ru/post/443124/
But these are already details.
React has a lazy method.
Example from documentation:
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}

Additionally <OtherComponent />, you can wrap in Suspense.
The problem is that dynamic import is used here. As I understand it, its support in browsers is not very good yet. Which means it doesn't suit me.
Further in the documentation:

React.lazy accepts a function that should call a dynamic import: import(). It should return a Promise that resolves to a module with
the React component's default export.

Is using dynamic import a prerequisite?
Or is it possible to return the promise yourself instead of using dynamic import?
If so, what is the right way to write it? Because all my attempts were unsuccessful.
In general, is it possible to cross lazy / Suspense with your own bicycle on promises through extreme selection and gene mutations?
Or maybe there are other alternatives.
Thanks in advance for any help in resolving the issue.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Anton Spirin, 2019-03-28
@rockon404

The problem is that dynamic import is used here. As I understand it, its support in browsers is not very good yet. Which means it doesn't suit me.

If you are not using a bundler like webpack in your project, then I have bad news for you.

L
lamer350, 2019-03-28
@lamer350

When you already understand that one request for one bundle is much faster than doing lazy loading by making additional requests to the server.
Yes, of course, at the first load, the rendering will take a little longer, but then this file is cached. And when loading separate scripts on the pages where they are used, it only slows it down, since time is wasted for loading individual scripts. Because everything is simple. In the header, we load the styles / js only that are needed to draw the first screen of the page, then we load everything into one bundle in the footer. Now there is no 2g where the speed was 10kb / s and you would have to wait 1 minute to download the whole bundle) In fact, the ping will most likely be higher than the download speed of the bundle with all scripts, especially if you use CDN...

V
Vitaly Yakovenko, 2019-03-28
@Xazzzi

If you have a bundler (webpack/rollup/etc), then the dynamic import will be moved to a separate chunk and the import() call will be converted into something more acceptable for current browsers, don't ride your bike, it's not necessary. But if you really want to, then you can return the promise to the es-module object yourself, react.lazy, no matter where you got it from.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question