Skip to content

fix: ActivityKeyerComposer perf#5790

Merged
OEvgeny merged 5 commits intomainfrom
fix/keyer-perf
Mar 27, 2026
Merged

fix: ActivityKeyerComposer perf#5790
OEvgeny merged 5 commits intomainfrom
fix/keyer-perf

Conversation

@OEvgeny
Copy link
Copy Markdown
Collaborator

@OEvgeny OEvgeny commented Mar 27, 2026

Fixes #

Changelog Entry

  • Improved ActivityKeyerComposer performance for append scenarios by adding an incremental fast path that only processes newly-appended activities, in PR #5790, by @OEvgeny

Description

ActivityKeyerComposer re-iterated all activities on every render to assign stable keys. With 1000+ streaming delta activities, each push triggered a full O(n) scan, making overall complexity growing towards O(n²) if we push fast enough. This PR adds an incremental fast path so only newly-appended activities are processed per render.

This implies that activities are immutable.

Design

The useMemo now uses a two-path strategy:

  1. Fast path (append-only): Compares the activities array prefix to the previous render using reference equality. When activities are only appended, only the new tail is iterated per render. Ref-held maps are mutated in-place so a single lookup covers both previous and current-iteration entries.
  2. Slow path (removal/reorder): Falls back to the original full-recalculation when the prefix diverges (items removed, replaced, or reordered).

This is still iterating the whole array, but since we need only ref checks, we spend only about 10% of the previous time on this work.

Specific Changes

  • Added prevActivitiesRef and prevActivityKeysStateRef refs to track previous render state
  • Added common-prefix detection to identify append-only changes in O(min(prev, next))
  • Added incremental fast path that processes only activities[commonPrefixLength..]
  • Kept maps mutable in refs (removed Object.freeze on Map instances) so the fast path can append in-place
  • Renamed shadowed activities variable to activitiesForKey in keyToActivitiesMap construction
  • Preserved the original full-recalculation as the slow path fallback

  • I have added tests and executed them locally
  • I have updated CHANGELOG.md
  • I have updated documentation

@OEvgeny OEvgeny changed the title wut fix: ActivityKeyerComposer perf Mar 27, 2026
@OEvgeny OEvgeny marked this pull request as ready for review March 27, 2026 17:31
@OEvgeny OEvgeny requested a review from a-b-r-o-w-n as a code owner March 27, 2026 17:31
Copilot AI review requested due to automatic review settings March 27, 2026 17:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves ActivityKeyerComposer key assignment performance during streaming/append-heavy updates by adding an incremental “append-only” fast path that avoids full rescans, while retaining a full recompute fallback for reorder/removal scenarios.

Changes:

  • Added common-prefix detection and an append-only incremental update path to process only newly appended activities.
  • Switched the internal key maps to mutable Maps held in refs to support in-place incremental updates.
  • Updated the changelog with an entry describing the performance improvement.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
packages/api/src/providers/ActivityKeyer/ActivityKeyerComposer.tsx Adds append-only incremental keying logic with ref-held mutable maps and a slow-path full recompute fallback.
CHANGELOG.md Documents the performance improvement in ActivityKeyerComposer.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@OEvgeny OEvgeny enabled auto-merge (squash) March 27, 2026 19:15
@OEvgeny OEvgeny merged commit 45490e5 into main Mar 27, 2026
59 of 60 checks passed
@OEvgeny OEvgeny deleted the fix/keyer-perf branch March 27, 2026 21:17
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.

3 participants