.changelog/3478.md
refreshFromRealmChanges() now only reloads games for the selected and already-loaded systems (instead of all systems sequentially), reducing Realm queries on each write from O(n) to O(loaded).loadAllGames() now loads system game lists concurrently (via TaskGroup) instead of one system at a time, speeding up the home shelf render.TVMediaSearchView now debounces the search text onChange by 300ms so Realm is not queried on every keystroke.TVMediaSystemShelfRow and TVMediaSystemHeader no longer hold a shared @ObservedObject on SystemIconLoader; icon rendering is delegated to a new TVMediaSystemIconView that scopes redraws to the icon only, preventing full-shelf invalidation when unrelated system icons load.ConsoleGamesView grid and list cells now use "\(id)_\(trueArtworkURL)" as their SwiftUI identity instead of the full model hashValue, so only artwork changes force view recreation rather than every Realm write touching playCount/lastPlayed.TVMediaSearchView recent-search chips now use the search string as their ForEach ID instead of array offset, preventing unnecessary redraws on search history reordering.systemsWithGames computed property no longer calls system.games.count (a live Realm query) as a fallback, using only the pre-loaded snapshot cache instead.showGamesGrid and showGamesList with Results<PVGame> now pass the Realm Results directly to ForEach instead of calling .toArray().filter {} on every render, eliminating full-library array allocation on each scroll frame.GeometryReader to measure container width; replaced with .frame(maxWidth: .infinity) centering, removing per-frame layout measurement during paging.HomeContinueSection now caches the current PVSaveState in @State and only re-resolves it on page/focus changes, avoiding a live Realm query in every body render.HomeView scroll-offset tracking moved to a reference-type ScrollTracker so that previousOffset mutations no longer trigger HomeView body re-evaluation on every pixel of scroll; isSearchBarVisible is now only written when its value actually changes.onAppear instead of calling relatedFiles.toArray() on every body re-render of each visible game cell.