perf: memoize @json model fields#7451
Conversation
Switch every @json-decorated WatermelonDB model field to the memoized form
({ memo: true }) so an unchanged nested JSON value keeps its reference identity
across reads, enabling per-field re-render bailout once consumers adopt it.
The memo cache is invalidated only when the raw column string changes, so
in-place mutation of a memoized value would silently corrupt it. Convert the
two remaining in-place mutations to replacement:
- ReactionsList sorts a copy ([...reactions].sort) instead of the field.
- encryption quote-attachment decryption reassigns message.attachments instead
of pushing into it.
Ref: NATIVE-1346
Claude-Session: https://claude.ai/code/session_01Cj1jHhEbiC9mWGe8dpqQeS
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (13)
📜 Recent review details⏰ Context from checks skipped due to timeout. (1)
🧰 Additional context used📓 Path-based instructions (6)**/*.{js,ts,jsx,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{js,jsx,ts,tsx,json}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{js,jsx,ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
app/lib/encryption/**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
app/containers/**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (2)📚 Learning: 2026-04-30T17:07:51.020ZApplied to files:
📚 Learning: 2026-06-25T18:37:44.793ZApplied to files:
🔇 Additional comments (14)
WalkthroughThe PR adds ChangesMemoized JSON decorators
Reaction sorting
Quote attachment append
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Warning Review ran into problems🔥 ProblemsErrors were encountered while retrieving linked issues. Errors (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Android Build Available Rocket.Chat 4.74.0.109230 Internal App Sharing: https://play.google.com/apps/test/RQQ8k09hlnQ/ahAO29uNSmEyPSO4q_7CaKdzMkIPaH9iUsLoE4e18oDwOebmN3E8C5rJVTmiK0Fmv-U0RKk5CTnQ2fBmeChuDvJc2v |
|
iOS Build Available Rocket.Chat 4.74.0.109231 |
Proposed changes
Switch every
@json-decorated WatermelonDB model field to the memoized form,@json('col', sanitizer, { memo: true }), across all 11 models (67 fields total). With memoization the decorator caches the[rawValue, sanitized]pair and returns the same object reference on every read while the underlying raw column string is unchanged. Today this is render-neutral; it sets up per-field re-render bailout for the consumers that adopt reference equality in later work.Because the memo cache is invalidated only when the raw column string changes, mutating a memoized value in place would silently corrupt the cache (the mutated object is returned again with a stale identity). This PR converts the two remaining in-place mutations of these fields to replacement:
ReactionsListsorts a copy ([...reactions].sort(...)) instead of sorting thereactionsfield in place.message.attachments = [...]instead ofpush()-ing into the existing array.Issue(s)
https://rocketchat.atlassian.net/browse/NATIVE-1346
How to test or reproduce
No behaviour change is expected — this is a reference-stability refactor. To confirm there is no re-render regression:
MessageContainerhad 0 re-renders (first-mount only) and theRoomViewcontrol had 0 re-renders in all trials of both the baseline and the memoized bundle. Commit totals stayed in the same band. The swap is render-neutral; the benefit lands when consumers start relying on the stable references.pnpm lint(0 errors) andTZ=UTC pnpm test(1770 passing) are green locally.Screenshots
N/A — no UI changes.
Types of changes
Checklist
Further comments
The two mutation fixes are required for correctness once
{ memo: true }is in place — without them a sort or an attachment append would return a stale cached reference. They are intentionally bundled with the memo swap rather than split out, since in isolation they are no-ops.Summary by CodeRabbit