Ich glaube, ich konnte es in einem Codespace reproduzieren, der auf diesem Branch basiert.
Ich habe es versucht, weil mir heute aufgefallen ist, dass die Zahlen im Benutzerverzeichnis manchmal falsch sind, und ich dachte, das könnte daran liegen, dass die Benutzer nicht geladen werden.
Beispiel für die falschen Zahlen, die mir aufgefallen sind:
Dies ist das Benutzerverzeichnis, wie es beim Öffnen aussieht. Zeitrahmen wöchentlich, sortiert nach erhaltenen Likes. Jetzt ändere ich die Reihenfolge zu Gelesene Beiträge:
Wie Sie sehen können, hat sich die Anzahl der Beiträge, die @lcor heute gelesen hat, nach dem Neuladen geändert. Zuvor passte sie nicht in die sortierte Liste.
Tatsächlich sind die 214 die Beiträge, die diese Woche gelesen wurden:
Dies war nicht das einzige Konto, bei dem die Zahlen beim Ausführen dieser Schritte den wöchentlichen statt den heutigen Zähler anzeigten. Es gibt mehr Benutzer, die so aussehen, als wären sie nicht an der richtigen Stelle, wo tatsächlich die wöchentlichen Zahlen angezeigt werden.
Nächste Benutzer in der Liste vor/nach dem Neuladen
Die Zahlen sind tatsächlich unterschiedlich, aber wichtiger ist, dass wir immer zwei Anfragen an den Endpunkt directory_items senden (eine mit und eine ohne die .json-Erweiterung), aber eine davon hat falsche Parameter
Ich kann es lokal jedoch nicht reproduzieren. Ich habe zwei verschiedene Anfragen, aber sie beziehen sich auf unterschiedliche Endpunkte (groups/search.json vs. directory_items)
Haben Sie versucht, mehr Benutzer zu Ihrer lokalen Installation hinzuzufügen? Ich frage mich, ob Sie mehr als 50 Benutzer benötigen, damit nicht alle gleichzeitig geladen werden. Ich glaube, die Benutzer, bei denen falsche Zahlen angezeigt wurden, waren diejenigen, die beim ersten Laden nicht sichtbar waren.
Ich habe versucht, einige Daten lokal zu cachen, damit wir bei jeder Änderung der Sortierreihenfolge/Spalte keine unnötigen Anfragen stellen müssen
Aber ich bin mir nicht sicher, ob dies die doppelte Anfrage / den Race Condition behebt, der in der Produktion auftritt, da ich ihn lokal nicht reproduzieren konnte
Dies war ein übler “Race Condition” zwischen dem “Sentinel”, den wir verwenden, um zu erkennen, wann wir die Aktion “Mehr laden” auslösen müssen, und dem Rendern der Zeilen im Benutzerverzeichnis
Das Problem
Wenn es mindestens 50 Benutzer gab, löste die Seite /u (Benutzerverzeichnis) loadMore sofort beim ersten Laden aus, bevor der Benutzer nach unten scrollen konnte. Dies führte dazu, dass automatisch eine unerwünschte zweite Seite mit Ergebnissen geladen wurde.
Grundursache
Race Condition während des anfänglichen Seitenladens:
Benutzer navigiert zu /u
controllers/users beginnt mit dem Laden von Daten (isLoading: true)
Die Vorlage wird mit ConditionalLoadingSpinner gerendert, der einen Spinner anzeigt
Daten kommen an, isLoading wird false
Der Spinner wird ausgeblendet, DirectoryTable beginnt mit dem Rendern von 50 Benutzern
Das Sentinel-Element für “Mehr laden” wird in das DOM eingefügt
Der IntersectionObserver wird erstellt und beginnt sofort mit der Beobachtung
Zu diesem Zeitpunkt berechnet die Tabelle noch das Layout/erweitert sich auf die volle Höhe
Das Sentinel ist kurzzeitig im Viewport sichtbar (ca. 292 Pixel von oben), bevor sich die Tabelle erweitert
Der Observer erkennt die Schnittmenge → löst loadMore aus
Die Tabelle erweitert sich vollständig auf die volle Höhe (ca. 3689 Pixel)
Das Sentinel bewegt sich an die richtige Position (ca. 3959 Pixel, unterhalb des Viewports)
Der Observer war “zu eifrig” – er begann mit der Beobachtung, bevor der Inhalt sein Layout abgeschlossen hatte, und fing das Sentinel in dem kurzen Moment ab, in dem die Tabelle noch nicht ihre endgültige Höhe erreicht hatte.
Die Lösung
Verzögern Sie die Erstellung des Observers, bis der Inhalt bereit ist:
Ein @isLoading-Parameter wurde zu LoadMore hinzugefügt, der verhindert, dass der IntersectionObserver erstellt wird, während der Inhalt noch geladen wird.
So funktioniert es jetzt
Seitenaufruf → isLoading=true → Modifier überspringt Observer-Erstellung
↓
Daten laden → isLoading=false → Modifier wird erneut ausgeführt, erstellt Observer
↓
Tabelle vollständig erweitert → Sentinel an der richtigen Position (unterhalb des Viewports)
↓
Benutzer scrollt nach unten → Sentinel tritt in den Viewport ein → loadMore wird ausgelöst ✓