You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[P1][Perf] Main thread bloccato: EventKit, notifiche e seed sincroni a ogni mutazione #12
CalendarSyncService è @MainActor: store.events(matching:) su 13 mesi (syncWindow) e il salvataggio di ogni evento girano sul main thread → UI congelata durante la sync.
TodoTask.touch() esegue in modo sincronostore.save(event) di EventKit a ogni mutazione. Le operazioni batch fanno N salvataggi uno dopo l'altro: "Riprogramma a oggi" (DashboardView.swift:515), drag nel Gantt, spostamenti multipli.
AppConfiguration.decode (JSON) viene rieseguito in ogni body di 13 viste (@AppStorage + computed configuration).
SeedService.ensureSeed viene chiamato a ogni creazione (vedi issue identità).
SeedService.repointWorkspace fa fetch di tutte le task senza predicato.
Fix proposto
@ModelActor di background per sync EventKit e import; il main riceve solo il merge.
Coda di side effect con coalescing (un flush ogni ~300 ms, un batch per operazione).
AppConfiguration come @Observable singleton decodificato una sola volta, con invalidazione alla modifica.
Creazioni: SeedService.identity(in:) legge spazio corrente e "me" salvati (due fetch per id); il seed completo (dedupe, membership, save) non gira più a ogni nuova attività/progetto/contatto, ma all'avvio e all'arrivo di dati iCloud (NSPersistentStoreRemoteChange, con debounce).
repointWorkspace / repointUser: fetch con predicato invece di tutte le righe; ripuntati anche contatti, crew e scene (prima restavano nello spazio eliminato).
AppConfiguration.decode era già in cache.
Resta:
CalendarSyncService sul main thread (events(matching:) su 13 mesi) → @ModelActor di background;
touch() con store.save EventKit sincrono a ogni mutazione → coda con coalescing (un batch per operazione).
la sync legge gli eventi della finestra (30 giorni indietro, 12 mesi avanti) in un task di background; sul main thread resta solo l'aggiornamento delle task;
le modifiche portate al calendario da touch() partono in un unico flush per raffica, con un solo store.commit(); gli eventi nuovi si salvano subito per avere l'eventIdentifier. Gli errori finiscono in lastError.
Resta: l'applicazione dell'import in un @ModelActor di background, utile per archivi molto grandi. Da provare su dispositivo con la sync attiva.
Problemi
CalendarSyncServiceè@MainActor:store.events(matching:)su 13 mesi (syncWindow) e il salvataggio di ogni evento girano sul main thread → UI congelata durante la sync.TodoTask.touch()esegue in modo sincronostore.save(event)di EventKit a ogni mutazione. Le operazioni batch fanno N salvataggi uno dopo l'altro: "Riprogramma a oggi" (DashboardView.swift:515), drag nel Gantt, spostamenti multipli.AppConfiguration.decode(JSON) viene rieseguito in ognibodydi 13 viste (@AppStorage+ computedconfiguration).SeedService.ensureSeedviene chiamato a ogni creazione (vedi issue identità).SeedService.repointWorkspacefa fetch di tutte le task senza predicato.Fix proposto
@ModelActordi background per sync EventKit e import; il main riceve solo il merge.AppConfigurationcome@Observablesingleton decodificato una sola volta, con invalidazione alla modifica.