Throttle member profile derivation to prevent reactive invalidation storm during space sync #251

Closed
opened 2026-04-29 01:24:32 +00:00 by nayan9617 · 3 comments
Contributor

Description

This is a sub-issue of #182.
When entering a space, SpaceMembers.svelte and RoomMembersAdd.svelte call deriveProfile(pubkey) individually for each member inside the render loop. Each call creates a separate reactive subscription. When a relay sync batch arrives — which delivers multiple profile events in quick succession — every subscription invalidates separately, triggering a full $derived recomputation cascade across all member components simultaneously.
For a space with 50 members, a single relay message burst causes up to 50 cascading reactive invalidations. This is a direct source of the GC pressure described in #182 — each invalidation cycle allocates new derived values before the previous ones are collected.

Proposed fix

wrap member profile derivations in throttled(300, ...) from @welshman/store, matching the pattern already used in src/app/editor/index.ts for profiles and deriveSpaceMembers. This batches invalidations into a single recomputation per 300ms window rather than one per event arrival.
Affected files: src/app/components/SpaceMembers.svelte, src/app/components/RoomMembersAdd.svelte

## Description This is a sub-issue of #182. When entering a space, SpaceMembers.svelte and RoomMembersAdd.svelte call deriveProfile(pubkey) individually for each member inside the render loop. Each call creates a separate reactive subscription. When a relay sync batch arrives — which delivers multiple profile events in quick succession — every subscription invalidates separately, triggering a full $derived recomputation cascade across all member components simultaneously. For a space with 50 members, a single relay message burst causes up to 50 cascading reactive invalidations. This is a direct source of the GC pressure described in #182 — each invalidation cycle allocates new derived values before the previous ones are collected. ## Proposed fix wrap member profile derivations in throttled(300, ...) from @welshman/store, matching the pattern already used in src/app/editor/index.ts for profiles and deriveSpaceMembers. This batches invalidations into a single recomputation per 300ms window rather than one per event arrival. Affected files: src/app/components/SpaceMembers.svelte, src/app/components/RoomMembersAdd.svelte
Author
Contributor

@hodlbod Happy to implement this if the approach looks right.

@hodlbod Happy to implement this if the approach looks right.
Owner

I'd like to see the fix, this sounds promising. It sounds like deriveDeduplicated or some other form of store caching could also be useful.

I'd like to see the fix, this sounds promising. It sounds like `deriveDeduplicated` or some other form of store caching could also be useful.
Author
Contributor

Thanks! I'll look into deriveDeduplicated as well — if it handles the dedup at the store level that might be cleaner than throttling alone. Will open a PR shortly.

Thanks! I'll look into deriveDeduplicated as well — if it handles the dedup at the store level that might be cleaner than throttling alone. Will open a PR shortly.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: coracle/flotilla#251