Skip to content

perf: comments-store deep clones via JSON.parse(JSON.stringify()), duplicating ~8 MB of strings #44

@tomcasaburi

Description

@tomcasaburi

Problem

comments-store.ts calls utils.clone() (which uses JSON.parse(JSON.stringify())) three times per comment:

  • Line 49: when saving to database
  • Line 52: when adding to Zustand store
  • Line 66: on comment updates

JSON.parse() creates new string instances for every property — V8 does not intern strings from JSON.parse. With ~26K comment objects on a typical board, this results in massive string duplication:

String Copies Wasted
ed25519 26,531 518 KB
1.0.0 26,528 518 KB
author 26,521 517 KB
business-and-finance.eth 16,180 562 KB
subplebbitAddress 16,569 517 KB
protocolVersion 15,652 427 KB
timestamp 16,563 388 KB
parentCid 15,487 362 KB
...and many more

Total: ~8 MB of duplicated strings in a single session.

Evidence

Measured via Chrome DevTools heap snapshots on 5chan (three snapshots: board page 1, catalog feed all 10 pages, reply section). The duplication counts are consistent across all three snapshots.

Existing pattern in the codebase

Two other stores already avoid this with an explicit comment:

replies-pages-store.ts (lines 96-97) and subplebbits-pages-store.ts (lines 98-99):

// don't clone the comment to save memory, comments remain a pointer to the page object
newComments[comment.cid] = comment

comments-store.ts should follow the same pattern.

Suggested fix

Remove utils.clone() calls in comments-store.ts and store comment references directly, matching replies-pages-store and subplebbits-pages-store. If cloning is required for some reason (e.g., preventing mutation), use shallow cloning ({ ...comment }) instead of deep cloning — this preserves shared string references.


Co-authored with Claude Opus 4.6 (heap snapshot analysis and plebbit-js source investigation).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions