Un loader UX-friendly en Angular avec cet utilitaire RxJS

un-loader-ux-friendly-en-angular-avec-cet-utilitaire-rxjs

🌀 Un loader UX-friendly en Angular avec RxJS

Afficher un loader trop rapidement peut provoquer un effet de “flash” désagréable. À l’inverse, le masquer trop tôt peut perturber l’utilisateur. Voici une solution simple et réutilisable avec RxJS pour un loader intelligent et fluide.

Lien stackblitz.

🎯 Objectif

  • Ne pas afficher le loader avant 200 ms, pour éviter les flashs inutiles.
  • Une fois qu’il est affiché, le maintenir visible au moins 2 secondes, pour assurer une expérience utilisateur stable.
  • Masquer le loader uniquement quand l’API a terminé de charger et que les 2 secondes sont écoulées.

🔧 Le code

// Timer déclenché après 200ms
const _passed200ms = timer(200).pipe(
  map(() => true),
  startWith(false)
);

// Timer déclenché après 2 secondes
const _passed2sDisplay = timer(2000).pipe(
  map(() => true),
  startWith(false)
);

// Fonction principale : retourne un Observable à consommer dans le template
function uiLoading$(isLoading$: Observable<boolean>) {
  return combineLatest([_passed200ms, _passed2sDisplay, isLoading$]).pipe(
    tap((data) => console.log('data', data)),
    map(([passed200ms, passed2sDisplay, isApiStillLoading]) => {
       map(([passed200ms, passed2sDisplay, isApiStillLoading]) => {
      if (!passed200ms) {
        return false;
      }

      // After 200ms: if still loading, show loader
      if (isApiStillLoading === true) {
        return true;
      }

      // API finished loading: only hide loader if 2s minimum display time passed
      if (isApiStillLoading === false && passed2sDisplay === true) {
        return false;
      }
      return false;
    }),
    }),
    distinctUntilChanged()
  );
}

🧪 Cas d’usage

🔹 Cas 1 : API lente → loader visible de 200ms à 5s

uiLoading$(
  of('data').pipe(
    delay(5000),
    map(() => false),
    startWith(true)
  )
).subscribe(result => console.log('result', result));

🔹 Cas 2 : API très rapide → le loader ne s’affiche jamais

uiLoading$(
  of('data').pipe(
    delay(50),
    map(() => false),
    startWith(true)
  )
).subscribe(result => console.log('result', result));

🔹 Cas 3 : API rapide mais pas instantanée → loader visible entre 200ms et 2s

uiLoading$(
  of('data').pipe(
    delay(1500),
    map(() => false),
    startWith(true)
  )
).subscribe(result => console.log('result', result));

✅ Avantages

  • 100 % réactif, sans variable d’état local ou setTimeout.
  • Composable : peut être utilisé dans n’importe quel composant Angular.
  • UX fluide : améliore la perception du chargement côté utilisateur.

Conseil perso: Fait en sorte de souscrire à cet observable directement dans ton template, cela va permettre au loader de s’adapter en conséquence.

Je m’excuse, je partage rapidement cet utilitaire, sans implémentation concrète. Toutefois, si tu as des questions ou si tu souhaites un example d’implémentation n’hésite pas.

Si l’article t’a plu ou si tu as des questions, n’hésite pas à laisser un commentaire ou encore à me suivre sur linkedin Romain Geffrault.

Total
0
Shares
Leave a Reply

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

Previous Post
how-to-pick-the-right-product-tools-for-your-team-–-moshe-mikanovsky-(product-coach)

How to pick the right product tools for your team – Moshe Mikanovsky (Product Coach)

Next Post
what-jobs-can-you-get-with-the-google-digital-marketing-certificate-in-2025?

What Jobs Can You Get with the Google Digital Marketing Certificate in 2025?

Related Posts