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/usersinizia a caricare i dati (isLoading: true)- Il template viene renderizzato mostrando lo spinner con
ConditionalLoadingSpinner - Arrivano i dati,
isLoadingdiventafalse - Lo spinner si nasconde,
DirectoryTableinizia 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
- L’Observer rileva l’intersezione → attiva
loadMore
- 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 ✓