Statistiques utilisateur incorrectes dans l'annuaire utilisateur

Ceci s’est avéré être une vilaine « condition de concurrence » entre le « sentinelle » que nous utilisons pour détecter quand nous devons déclencher l’action « charger plus » et le rendu des lignes dans le répertoire des utilisateurs :exploding_head:

Le problème

Quand il y avait au moins 50 utilisateurs, la page /u (répertoire des utilisateurs) déclenchait loadMore immédiatement au premier chargement, avant que l’utilisateur ne puisse faire défiler la page. Cela entraînait le chargement automatique d’une deuxième page de résultats indésirable.

Cause profonde

Condition de concurrence de synchronisation lors du chargement initial de la page :

  1. L’utilisateur navigue vers /u
  2. controllers/users commence à charger les données (isLoading: true)
  3. Le modèle se rend avec ConditionalLoadingSpinner affichant le spinner
  4. Les données arrivent, isLoading devient false
  5. Le spinner se masque, DirectoryTable commence à rendre 50 utilisateurs
  6. L’élément sentinelle LoadMore est inséré dans le DOM
  7. IntersectionObserver est créé et commence à observer immédiatement
  8. À ce moment, le tableau calcule encore la mise en page/s’étend à sa pleine hauteur
  9. Le sentinelle est brièvement visible dans le viewport (~292px du haut) avant que le tableau ne s’étende
  10. L’observateur détecte l’intersection → déclenche loadMore :cross_mark:
  11. Le tableau finit de s’étendre à sa pleine hauteur (~3689px)
  12. Le sentinelle se déplace à la bonne position (~3959px, sous le viewport)

L’observateur était « trop impatient » - il a commencé à observer avant que le contenu n’ait fini sa mise en page, capturant le sentinelle pendant le bref moment où le tableau n’avait pas encore atteint sa hauteur finale.

La correction

Retarder la création de l’observateur jusqu’à ce que le contenu soit prêt :

Ajout d’un paramètre @isLoading à LoadMore qui empêche la création de IntersectionObserver lorsque le contenu est encore en cours de chargement.

Comment ça marche maintenant

Chargement de la page → isLoading=true → Le modificateur saute la création de l'observateur
             ↓
Chargement des données → isLoading=false → Le modificateur s'exécute à nouveau, crée l'observateur
             ↓
Tableau entièrement étendu → Sentinelle à la bonne position (sous le viewport)
             ↓
L'utilisateur fait défiler la page → Le sentinelle entre dans le viewport → loadMore se déclenche ✓

5 « J'aime »