SOMMAIRE

Envie d’aller plus loin ? Échangez directement avec l’un de nos experts.

Chaque appel API a un coût. Sur une application Angular, mettre en place un cache Front sur les données référentielles est l’un des gestes les plus rentables pour réduire ce coût, à la fois en performance et en empreinte environnementale.

Un aller-retour réseau, du temps de calcul côté serveur, souvent plusieurs requêtes en base de données, une ligne de log stockée quelque part : multiplié par des milliers d’utilisateurs et des millions de requêtes par jour, ce coût devient significatif, en charge sur les infrastructures client, réseau et serveur, en énergie consommée, et en performance unitaire ou en charge.

Le référentiel d’écoconception des services numériques (RGESN) recommande de minimiser le nombre de requêtes et de réduire les échanges réseau. Une des approches les plus simples et les plus rentables pour respecter ce principe côté Frontend concerne justement ces données référentielles : la liste de pays, de statuts, des unités de mesure, des nomenclatures métier. Des données qui changent rarement, mais qui sont sollicitées très souvent.

Cet article propose une méthode concrète, avec des exemples en Angular, pour mettre en place un cache Front efficace sur ces données. Nous verrons d’abord pourquoi ce type de données s’y prête particulièrement bien, puis nous passerons en revue plusieurs stratégies d’implémentation, du plus simple au plus robuste. Nous mesurerons ensuite l’impact concret de ces choix côté écoconception, avant de conclure sur quelques bonnes pratiques à garder en tête pour éviter les pièges classiques.

Commençons par comprendre ce qui rend les données référentielles particulièrement adaptées à la mise en cache.

Pourquoi les données référentielles sont-elles idéales pour un cache Front ?

Les données référentielles partagent trois caractéristiques qui en font le candidat parfait pour la mise en cache :

  • Faible volatilité : une liste de pays ou de statuts change rarement, parfois jamais dans la durée de vie d’une session.
  • Forte réutilisation : la même liste est souvent appelée par plusieurs composants (formulaires, filtres, tableaux).
  • Faible personnalisation : contrairement à des données métier, elles sont identiques pour tous les utilisateurs.

Prenons un exemple concret : un écran de saisie avec cinq menus déroulants (pays, statut, type, unité, catégorie). Sans cache, chaque ouverture d’écran déclenche cinq appels API, potentiellement à chaque navigation, même si l’utilisateur revient sur le même écran dix fois dans sa session.

Exemple sans cache front

À retenir :

À l’échelle d’une application avec quelques milliers d’utilisateurs actifs par jour, ce sont des dizaines de milliers de requêtes évitables qui sont envoyées inutilement au Backend, pour des données qui n’ont pas changé depuis la veille.

Exemple avec cache front

Mais concrètement, en quoi ces requêtes évitées comptent-elles pour l’écoconception ?
Moins de requêtes envoyées vers le Backend produit un effet en chaîne, du serveur jusqu’à l’infrastructure :

  • Moins de sollicitation CPU et mémoire côté serveur, à chaque requête évitée.
  • Moins de trafic réseau, donc moins de données transportées et d’énergie consommée sur le trajet.
  • Une base de données moins sollicitée, avec moins de lectures répétées sur des données qui n’ont pas changé.
  • La possibilité de redimensionner l’infrastructure Backend à la baisse : moins d’instances, moins de replicas.

Voyons maintenant concrètement comment implémenter ce cache avec Angular, du mécanisme le plus simple au plus robuste.

4 stratégies de cache Front en Angular

Avec Angular, plusieurs niveaux de cache sont possibles, du plus simple au plus robuste. Voici quatre approches complémentaires, à choisir selon la criticité et la fréquence de changement des données.

shareReplay : le cache mémoire le plus simple

La technique la plus simple consiste à utiliser l’opérateur RxJS – shareReplay. Concrètement, cet opérateur fait deux choses : il partage un seul et même Observable entre tous les abonnés (au lieu de relancer un appel HTTP à chaque souscription), et il rejoue la dernière valeur émise (« replay ») à tout nouvel abonné qui arrive après coup (même s’il s’abonne longtemps après l’appel initial).

Ainsi, le premier appel déclenche la requête http. Puis tous les appels suivants réutilisent la même réponse, sans nouvel appel réseau.

Cette approche est simple à mettre en place, sans dépendance externe, et ne déclenche qu’un seul appel réseau tant que le cache reste valide. En pratique, elle reste toutefois liée au cycle de vie de la page : le cache est perdu au rechargement (F5), et sans windowTime, il n’expire jamais tant qu’au moins un composant reste abonné. Avec refCount: true, il est simplement réinitialisé dès que plus personne n’écoute.

Pour des données un peu plus sensibles au changement, justement, il faut aller plus loin qu’un simple cache mémoire.

Cache Map avec TTL : gérer l’expiration côté Front

Pour éviter de servir une donnée périmée trop longtemps, on ajoute une durée de vie (Time To Live). Passé un certain délai, le cache est invalidé automatiquement, ce qui force un rafraîchissement périodique sans multiplier les appels inutiles.

Cache front angular - cache map ttl

Ce mécanisme convient bien aux données référentielles à durée de vie modérée (ex : unités de mesure, catégories métier), où un léger décalage temporel est acceptable.

Quand les données changent encore plus rarement, le cache peut aller plus loin et survivre au-delà de la session elle-même.

Persistance inter-sessions avec localStorage

Pour des données référentielles qui changent très rarement, par exemple une fois par semaine ou par mois, il est pertinent de conserver le cache au-delà de la session : le localStorage. On applique alors une stratégie « stale-while-revalidate » : on affiche immédiatement la donnée en cache, tout en revalidant en arrière-plan.

persistance inter sessions local Storage - cache front angular

Voici comment on l’implémente :

implémentation localStorage

Cette approche permet d’éviter des appels réseau même au premier chargement d’une nouvelle session utilisateur, mais elle demande un peu plus de rigueur :

  • Gérer la taille du storage disponible (dépend du quota du navigateur)
  • Sérialiser et désérialiser correctement les données mises en cache.

Mais quelle que soit la durée de persistance choisie, encore faut-il savoir avec certitude quand ce cache doit être rafraîchi.

Invalidation par version : garder un cache fiable

Le risque du cache long terme est de servir une donnée obsolète sans le savoir. La solution consiste à faire porter au Backend la responsabilité de signaler un changement, via un champ de version par exemple.

Le Front compare la version en cache à la version courante (via un endpoint léger de type /api/referentiels/version) avant de décider de réutiliser le cache ou de le rafraîchir. Cette vérification est elle-même très légère (quelques octets), ce qui reste largement plus économe qu’un rechargement complet de la liste.

Ceci s’applique aux deux cas précédents de cache Map en mémoire ou LocalStorage dans la vérification du contenu déjà caché.

Bonne pratique :

Ne jamais invalider « à l’aveugle » sur simple durée. Combiner un TTL raisonnable (garde-fou) avec une vérification de version permet d’avoir un cache à la fois économe et fiable.

Maintenant que ces mécanismes sont posés, reste à évaluer ce qu’ils changent réellement, à la fois pour l’utilisateur et pour l’infrastructure Backend.

Ce que le cache Front change vraiment pour l’écoconception

Le tableau ci-dessous illustre, à titre indicatif, l’effet d’une stratégie de cache Front sur les données référentielles pour une application avec un trafic modéré.

Indicateur

Sans cache Front

Avec cache Front

Requêtes / liste référentielle / session

5 à 15 appels

1 appel (puis cache)

Volume de données transféré / jour (10K users)

⁓ 2 à 5 Go

⁓ 200 à 400 Mo

Temps de réponse perçu (2e affichage)

150-400 ms (réseau)

<5 ms (mémoire)

Charge CPU / mémoire Backend

Proportionnelle au trafic

Réduite, plus stable

Dimensionnement infra nécessaire

Pics à absorber

Marge de réduction possible

Au-delà des chiffres, deux effets concrets sur le Backend :

  • Réduction de la charge CPU/mémoire : moins de requêtes traitées signifie moins de cycles de calcul et moins de connexions base de données ouvertes simultanément.
  • Réduction du dimensionnement nécessaire : un service moins sollicité en pic peut fonctionner avec moins de réplicas ou des instances plus petites, ce qui réduit directement la consommation énergétique de l’infrastructure.

Pour objectiver ces gains sur un projet réel, plusieurs outils permettent de mesurer avant/après :

  • L’onglet Network des DevTools navigateur, pour compter et peser les requêtes
  • Lighthouse, pour évaluer l’impact sur les performances perçues,
  • Des outils dédiés à l’écoconception comme GreenIT-Analysis ou EcoIndex pour estimer l’empreinte environnementale d’un parcours utilisateur.

Ces gains ne sont toutefois acquis que si le cache est mis en œuvre avec rigueur en gardant en tête quelques points de vigilance.

Bonnes pratiques et pièges à éviter

Voici quelques recommandations à prendre en compte lors de la mise en cache des données :

  • Ne jamais mettre en cache des données sensibles ou personnelles, même « référentielles » en apparence comme les droits utilisateurs par exemple.
  • Toujours prévoir un mécanisme de repli si le cache est vide, corrompu ou indisponible, comme dans le cas du quota du localStorage qui est dépassé.
  • Ne pas confondre données référentielles (stables) et données métier (volatiles) : le sur-cache de données changeantes crée des bugs difficiles à diagnostiquer.
  • Documenter la stratégie de cache pour l’équipe : durée de vie, mécanismes d’invalidation, périmètre des données concernées.
  • Prévoir un bouton ou une commande de purge du cache pour les supports et les tests.

Conclusion

Mettre en place un cache front pour les données référentielles est un geste technique simple, peu coûteux à développer, qui répond concrètement à l’objectif d’écoconception de minimisation des requêtes. Il réduit les échanges réseau, améliore l’expérience utilisateur perçue, et ouvre la voie à un dimensionnement Backend plus sobre.

Cette approche gagne à être combinée à d’autres bonnes pratiques d’écoconception Frontend :

  • Compression des réponses,
  • Lazy loading des modules
  • Pagination des listes volumineuses.

Ensemble, elles forment une stratégie cohérente de sobriété numérique, à l’échelle de toute l’application.

Et pour aller plus loin, une prochaine étape naturelle consiste à factoriser cette logique dans un service générique de cache réutilisable dans toute l’application, voire à en faire une petite librairie interne partagée entre équipes.

Ne ratez plus aucune actualité avec la newsletter mensuelle de SoftFluent

Newsletter SoftFluent