Lazy loading of routes causing flickering issue

Loading

Lazy loading in Angular, React, Vue, or other frameworks is a great way to improve performance by loading modules or components only when needed. However, it can cause a flickering issue where a blank screen or default state appears briefly before the content loads. Below, I’ll explain why this happens and how to fix it.


1. Why Does the Flickering Issue Occur?

The flickering issue in lazy loading usually happens due to:

  1. No Proper Loading Indicator
    • When a route is being lazily loaded, there is a delay before the component appears, causing a blank screen.
  2. Route Module Not Preloaded
    • If lazy-loaded modules take longer to load, the transition may appear jarring.
  3. CSS or Styling Issues
    • A delay in applying styles can result in a quick flash of unstyled content.
  4. Multiple Renders in React (Strict Mode)
    • In React, React.StrictMode may cause components to mount and unmount multiple times in development.
  5. Slow Network or API Calls
    • If the page depends on API data, it might show a blank UI before the content is fetched.

2. How to Fix Flickering Issues in Lazy Loaded Routes?

Solution 1: Use a Loading Indicator (Skeleton or Spinner)

A simple loading spinner or skeleton screen can prevent the flickering effect by showing a placeholder while the content is loading.

Angular Example

Modify app-routing.module.ts:

const routes: Routes = [
{
path: 'dashboard',
loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule),
data: { preload: true }
}
];

Then, in the parent component:

<ng-container *ngIf="isLoading; else loadedContent">
<app-spinner></app-spinner> <!-- Show spinner while loading -->
</ng-container>
<ng-template #loadedContent>
<router-outlet></router-outlet>
</ng-template>

React Example

const LazyComponent = React.lazy(() => import("./Dashboard"));

function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyComponent />
</Suspense>
);
}

Why This Works?
The fallback component shows until the module is loaded, preventing flickering.


Solution 2: Preloading Lazy-Loaded Modules

To avoid delays in loading, you can preload lazy-loaded modules in Angular.

Angular Preloading Strategy

Modify app-routing.module.ts:

import { PreloadAllModules } from '@angular/router';

const routes: Routes = [
{
path: 'dashboard',
loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule)
}
];

@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
exports: [RouterModule]
})
export class AppRoutingModule { }

Why This Works?

  • Modules will load in the background, reducing flickering when the user navigates.

Solution 3: Optimize CSS and Avoid Flash of Unstyled Content (FOUC)

Sometimes, styles are loaded after the component, causing a brief flicker.
Fix: Ensure styles are preloaded or use CSS inlining.

Example:

<link rel="stylesheet" href="styles.css" as="style" onload="this.rel='stylesheet'">

Why This Works?

  • It ensures styles are applied before the page loads, preventing the flicker.

Solution 4: Prevent Multiple Mounting in React

In React, React.StrictMode in development causes double rendering. You can disable it in index.js:

<React.StrictMode>
<App />
</React.StrictMode>

Remove StrictMode in production builds if it causes flickering.


Solution 5: Use Route-Level Caching to Avoid Reloading

If the issue occurs every time the user navigates, caching previously loaded components helps.

Angular Example: Route Reuse Strategy

Modify app-routing.module.ts:

import { RouteReuseStrategy } from '@angular/router';

@NgModule({
providers: [{ provide: RouteReuseStrategy, useClass: CustomReuseStrategy }]
})
export class AppModule { }

Then, create CustomReuseStrategy.ts:

export class CustomReuseStrategy implements RouteReuseStrategy {
shouldDetach(): boolean { return true; }
store(): void {}
shouldAttach(): boolean { return true; }
retrieve(): any { return null; }
shouldReuseRoute(): boolean { return true; }
}

Why This Works?
It caches routes, preventing flickering when switching back to a lazy-loaded module.

Leave a Reply

Your email address will not be published. Required fields are marked *