Files
multica/packages/views/issues
Bohan Jiang d0c66f3173 perf(issue-detail): memoize timeline render to mitigate Inbox long-timeline freeze (#2025)
* perf(issue-detail): memoize timeline render to fix Inbox long-timeline freeze

On long-timeline issues (thousands of comments), opening from Inbox hard-freezes
the browser tab because every WS-driven parent re-render re-runs the full
react-markdown + rehype-* + lowlight pipeline for every comment. This is the
S3 mitigation for multica#1968:

- Wrap ReadonlyContent in React.memo so equal-content re-renders skip the
  markdown pipeline entirely (the dominant cost per comment).
- Wrap CommentCard in React.memo so unrelated parent state updates don't
  re-render every card.
- useMemo the timeline grouping in IssueDetail so the allReplies Map and
  groups array references are stable across re-renders that don't change
  timeline.
- Stabilize toggleReaction via a timelineRef so its identity doesn't change
  on every WS event, which previously defeated CommentCard memoization.

Virtualization (S2) is the root fix for first-paint cost and lands separately.

Co-authored-by: multica-agent <github@multica.ai>

* fix(issue-detail): destructure mutate/mutateAsync so CommentCard memo holds

Per review on PR #2025: TanStack Query v5 returns a fresh result wrapper
from useMutation on every render, with only the inner mutate / mutateAsync
functions guaranteed stable. The previous useCallback dependencies listed
the whole mutation object, so on every parent re-render the callbacks
flipped identity — defeating React.memo on CommentCard and leaving the
long-timeline mitigation only half-effective.

Pull just the stable handles into deps. Add a renderHook-based regression
test that re-renders useIssueTimeline twice and asserts the four callbacks
passed to CommentCard keep the same identity.

Co-authored-by: multica-agent <github@multica.ai>

---------

Co-authored-by: multica-agent <github@multica.ai>
2026-05-03 11:57:30 +08:00
..