Je pense avoir réussi à le reproduire dans un Codespace créé à partir de cette branche.
J’ai essayé parce qu’aujourd’hui j’ai remarqué que parfois les chiffres dans le répertoire des utilisateurs sont incorrects et j’ai pensé que c’était peut-être dû au problème de chargement des utilisateurs.
Voici le répertoire des utilisateurs tel qu’il apparaît à l’ouverture. Période : hebdomadaire, trié par likes reçus. Maintenant, je change le tri par “Posts lus” :
Comme vous pouvez le voir, le nombre de posts lus par @lcor aujourd’hui a changé après le rechargement. Avant, il ne rentrait pas dans la liste triée.
En fait, les 214 sont les posts lus cette semaine :
Ce n’était pas le seul compte où les chiffres affichaient le compte hebdomadaire au lieu d’aujourd’hui lorsque j’ai effectué ces étapes. Il y a d’autres utilisateurs qui semblent ne pas être à la bonne place, où les chiffres hebdomadaires sont en fait affichés.
Utilisateurs suivants dans la liste avant/après rechargement
Les nombres sont effectivement différents, mais le plus important est que nous faisons toujours deux requêtes vers le point de terminaison directory_items (une avec et l’autre sans l’extension .json), mais l’une d’elles a des paramètres incorrects
Cependant, je ne peux pas reproduire localement, j’ai deux requêtes différentes, mais elles concernent des points de terminaison différents (groups/search.json vs directory_items)
Avez-vous essayé d’ajouter plus d’utilisateurs à votre installation locale ? Je me demande si vous avez besoin de plus de 50 utilisateurs, afin qu’ils ne soient pas tous chargés en même temps.
Je pense que les utilisateurs qui affichent de mauvais chiffres sont ceux qui n’étaient pas visibles au premier chargement.
J’ai essayé de mettre en cache des données localement afin de ne pas effectuer de requêtes inutiles à chaque changement d’ordre/colonne de tri
Mais je ne suis pas sûr que cela résolve la double requête / condition de concurrence qui se produit en production car je n’ai pas pu la reproduire localement
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
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 :
L’utilisateur navigue vers /u
controllers/users commence à charger les données (isLoading: true)
Le modèle se rend avec ConditionalLoadingSpinner affichant le spinner
Les données arrivent, isLoading devient false
Le spinner se masque, DirectoryTable commence à rendre 50 utilisateurs
L’élément sentinelle LoadMore est inséré dans le DOM
IntersectionObserver est créé et commence à observer immédiatement
À ce moment, le tableau calcule encore la mise en page/s’étend à sa pleine hauteur
Le sentinelle est brièvement visible dans le viewport (~292px du haut) avant que le tableau ne s’étende
Le tableau finit de s’étendre à sa pleine hauteur (~3689px)
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 ✓