Scroll perf: drop hot-path logs, pure filter, cached results
Created by: jedmund
Summary
Addresses the scroll-jank report in the illust detail view. From a code-review audit plus Time Profiler verification, three changes land here; the user confirms the trace no longer shows hiccups during detail-with-related-posts scroll.
-
Drop per-frame
Loggercalls on the cell hot path.IllustFeedCell.onGeometryChangefiredheroLog.debug("cell onGeom id=… rect=…")every layout frame per visible cell — string-interpolating a formatted CGRect.CellRectRegistry.rect(for:)firedheroLog.notice(…)enhancement×/sec during dismiss-pan. Both gone. Can be re-added behind a compile-time flag if hero-transition debugging ever needs them back. -
Remove body-level view-model writes.
IllustFeedView.bodywas writingviewModel.mutes = MutesBridge.shared.currentandviewModel.muteBehavior = muteBehaviorevery render. ReplacedvisibleIllustscomputed with a purefilteredIllusts(behavior:mutes:)method the view calls with its own@AppStorage+MutesBridgereads. Pagination'sloadMoreIfNeedednow takesvisibleCountas an explicit parameter. -
Cache the mute filter.
MutesStore.versionbumps on every mute/unmute/refresh;IllustFeedViewModel.illustsVersionbumps on everyillustsmutation.filteredIllustskeys its cache on(illustsVersion, mutesVersion, mutes identity, behavior), so pure-scroll renders skip the O(n) walk entirely — filter only runs again when state actually changes.
Deferred (noted in the audit, not in this PR)
- F2 —
UIHostingController.sizingOptions = .intrinsicContentSizethrash in the related-posts nested grid. No longer suspected to be the primary jank source; will revisit only if a future regression points back to it. - Tier 2 —
MasonryDistribution.distributeon column reflow,@AppStoragecell reads. Fine on current traces. - Tier 3 — thread-safety polish (explicit
@MainActoronAuthSessiontasks,TTLDataCachesweep cancel,SearchViewtask cancel on dismiss,BookmarksIndexObservabledeinit cancel). Separate branch.
Test plan
-
Scroll Home rapidly; confirm frame-drops absent. -
Open a detail with related posts, scroll into the related grid for several seconds — no hiccups. -
Mute a user from a profile → feed drops them immediately. -
Unmute from Settings → Muted Users → posts return on next load-more. -
Toggle Settings → Mute behavior between Fully hide / Obscured → feed switches immediately. -
Pull-to-refresh Home + Tag feed. -
Bookmark/unbookmark a cell from the detail view → grid's heart state updates without re-fetch. -
Hero push/pop animates correctly (removed CellRectRegistry logs were diagnostic, the animator's source-rect path is hot).