Skip to content

perf: avoid O(N^2) indexOf in notifications list#491

Merged
barrydeen merged 1 commit intomainfrom
fix/notifications-freeze-indexof
Apr 23, 2026
Merged

perf: avoid O(N^2) indexOf in notifications list#491
barrydeen merged 1 commit intomainfrom
fix/notifications-freeze-indexof

Conversation

@barrydeen
Copy link
Copy Markdown
Owner

Summary

  • Users (notably on GrapheneOS) reported the app freezing when tapping the Notifications bottom-nav tab.
  • Root cause: inside the LazyColumn items { … } lambda we called notifications.indexOf(item) on every item composition. That's a linear scan per item → O(N²) total work per recomposition pass, with each scan invoking FlatNotificationItem.equals (data class). With a few hundred notifications and frequent profileVersion bumps invalidating the list, this is enough to stall the main thread long enough to look like a freeze on slower hardware.
  • Fix: switch to itemsIndexed(...) and use the supplied index directly. One-line behavioral equivalent, no more quadratic scan.

Test plan

  • Open the Notifications tab on a populated account; verify list renders and scrolls smoothly
  • Tap a notification to expand/collapse (uses itemIndex for animateScrollToItem) and confirm scroll-to-item still lands correctly when replying
  • Pull to refresh; confirm ordering and summary header are unchanged
  • Ideally: have a GrapheneOS user confirm the freeze on tab switch is gone

Replace items(...) + notifications.indexOf(item) with itemsIndexed(...)
in NotificationsScreen. The indexOf call ran during composition for
every visible item, causing a linear scan per item and quadratic total
work as the list grew. Reported as a UI freeze when tapping the
notifications tab on slower devices (GrapheneOS).
@barrydeen barrydeen merged commit b609fc5 into main Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant