Penso di essere riuscito a riprodurlo in un Codespace creato sulla base di quel branch.
Ho provato perché oggi ho notato che a volte i numeri nella directory utente sono errati e ho pensato che forse fosse dovuto al problema per cui gli utenti non vengono caricati.
Questa è la directory utente come appare quando la si apre. Intervallo di tempo settimanale, ordinato per like ricevuti. Ora cambio l’ordinamento in Post letti:
Come puoi vedere, il numero di post letti da @lcor oggi è cambiato dopo il ricaricamento. Prima, non rientrava nell’elenco ordinato.
In realtà, i 214 sono i post letti questa settimana:
Non è stato l’unico account in cui i numeri mostravano il conteggio settimanale invece di quello odierno quando ho eseguito questi passaggi. Ci sono più utenti che sembrano non essere al posto giusto, dove in realtà vengono mostrati i numeri settimanali.
Prossimi utenti nell'elenco prima/dopo il ricaricamento
I numeri sono effettivamente diversi, ma ciò che è più importante è che stiamo sempre facendo due richieste all’endpoint directory_items (una con, l’altra senza l’estensione .json), ma una di esse ha parametri errati
Tuttavia, non riesco a riprodurlo localmente, ho due richieste diverse, ma sono su endpoint diversi (groups/search.json vs directory_items)
Hai provato ad aggiungere più utenti alla tua installazione locale? Mi chiedo se ne servano più di 50, in modo che non vengano caricati tutti contemporaneamente.
Penso che gli utenti che mostrano numeri errati fossero quelli non visibili al primo caricamento.
Ho provato a memorizzare nella cache alcuni dati localmente in modo da non effettuare richieste non necessarie ad ogni modifica dell’ordine/colonna di ordinamento
Ma non sono sicuro che risolverà la doppia richiesta / race condition che si verifica in produzione poiché non sono stato in grado di riprodurla localmente
Si è verificata una brutta “race condition” tra il “sentinel” che usiamo per rilevare quando dobbiamo attivare l’azione “carica altro” e il rendering delle righe nella directory degli utenti
Il problema
Quando c’erano almeno 50 utenti, la pagina /u (directory utenti) attivava loadMore immediatamente al primo caricamento, prima che l’utente potesse scorrere verso il basso. Ciò causava il caricamento automatico di una seconda pagina di risultati indesiderata.
Causa principale
Race condition temporale durante il caricamento iniziale della pagina:
L’utente naviga in /u
controllers/users inizia a caricare i dati (isLoading: true)
Il template viene renderizzato mostrando lo spinner con ConditionalLoadingSpinner
Arrivano i dati, isLoading diventa false
Lo spinner si nasconde, DirectoryTable inizia a renderizzare 50 utenti
L’elemento sentinel LoadMore viene inserito nel DOM
IntersectionObserver viene creato e inizia a osservare immediatamente
In questo momento, la tabella sta ancora calcolando il layout/espandendosi all’altezza completa
Il sentinel è brevemente visibile nel viewport (~292px dall’alto) prima che la tabella si espanda
La tabella finisce di espandersi all’altezza completa (~3689px)
Il sentinel si sposta nella posizione corretta (~3959px, sotto il viewport)
L’observer era “troppo zelante”: ha iniziato a osservare prima che il contenuto finisse il suo layout, catturando il sentinel durante il breve momento in cui la tabella non aveva ancora raggiunto la sua altezza finale.
La soluzione
Ritarda la creazione dell’observer finché il contenuto non è pronto:
Aggiunto un parametro @isLoading a LoadMore che impedisce la creazione di IntersectionObserver quando il contenuto è ancora in fase di caricamento.
Come funziona ora
Caricamento pagina → isLoading=true → Modifier salta la creazione dell'observer
↓
Caricamento dati → isLoading=false → Modifier riesegue, crea l'observer
↓
Tabella completamente espansa → Sentinel nella posizione corretta (sotto il viewport)
↓
L'utente scorre verso il basso → Il sentinel entra nel viewport → loadMore si attiva ✓