loading...

Discussion on: Trying Lazy Loading and getting flicker?

Collapse
glebirovich profile image
Gleb Irovich

Hey! You see flickering because loading happens too fast and spinner changes immediately to the route content. You can try setting a minimal delay, since lazy can return regular Promise.

const Food = lazy(() => Promise.all([
  import('./components/Food'),
  new Promise((resolve) => setTimeout(resolve, 3000)) // ensures minimal delay
 ]).then(([module]) => module)
);

or create a function out of it, which would reduce the boilerplate:

const lazyDelayed = (path: string, delay = 3000) => {
  return lazy(() => Promise.all([
    import(path),
    new Promise((resolve) => setTimeout(resolve, delay)) // ensures minimal delay
  ]).then(([module]) => module));
}

const Food = lazyDelayed('./components/Food')
Collapse
bmitchinson profile image
Ben Mitchinson Author

@gleb Thanks for this suggestion, it's behaving like you described "loading happens too fast and spinner changes immediately to the route content"

I tried your solution, and it added a delay to the load, where the white screen was extended by 3 seconds, then went to the component. Did you get this solution from here? stackoverflow.com/questions/541589...

I'm still don't understand the difference between the first and second solutions listed there in that SO post. Tried both to no avail.

I'll try to create something reproducible in typescript create-react-app.

Collapse
glebirovich profile image
Gleb Irovich

I would suspect then that your HOC not returning properly. Could you validate if spinner is shown without using hoc?

Collapse
glebirovich profile image
Gleb Irovich

Here is a short working demo:
github.com/GlebIrovich/suspense-demo

I think something is wrong with the HOC. Because if you look at my implementation, valid Route can only accept HOC like a that: <Route path="/changePassword" exact={true} component={() => withHOC(LazyContent)} />

Hope it helps

Collapse
glebirovich profile image
Gleb Irovich

Regarding the solution on SO.
First one adds time on top of the time required for import. So if import takes 2 sec and delay is 3 sec, totally it will take 5 sec.
The second approach uses Promise.all, which makes the same work "in parallel". So if import takes 2 sec and delay is 3 sec, totally it will take 3 sec. So the operation will take AT LEAST the time specified in the delay.