DEV Community

Discussion on: Trying Lazy Loading and getting flicker?

Collapse
 
glebirovich profile image
Gleb Irovich • Edited

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)
);
Enter fullscreen mode Exit fullscreen mode

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')
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bmitchinson profile image
Ben Mitchinson • Edited

@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.

Collapse
 
vinaysharma14 profile image
Vinay Sharma

Hi Gleb, creating a reusable function results in the following error:

Error: Cannot find module './Home'