RoomsListView: freeze when blurred to avoid off-screen re-renders on room open#7404
RoomsListView: freeze when blurred to avoid off-screen re-renders on room open#7404diegolmello wants to merge 1 commit into
Conversation
WalkthroughThe ChangesRoomsListView Screen Option
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~2 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
app/stacks/InsideStack.tsx (1)
103-103: ⚡ Quick winConsider adding an explanatory comment for the freezeOnBlur configuration.
The coding guidelines state: "Write comments that explain the 'why' behind code decisions, not the 'what'." While the PR objectives clearly document the rationale (preventing off-screen re-renders during RoomView transitions), the code itself lacks inline documentation. A brief comment would help future maintainers understand the performance motivation.
💡 Example comment
- <ChatsStack.Screen name='RoomsListView' component={RoomsListView} options={{ freezeOnBlur: true }} /> + {/* Freeze rendering when list is blurred (e.g., RoomView pushed on top) to prevent + unnecessary re-renders of off-screen RoomItem components during transitions. + WatermelonDB subscription remains active, ensuring data consistency on return. */} + <ChatsStack.Screen name='RoomsListView' component={RoomsListView} options={{ freezeOnBlur: true }} />Alternatively, a single-line comment if you prefer brevity:
- <ChatsStack.Screen name='RoomsListView' component={RoomsListView} options={{ freezeOnBlur: true }} /> + {/* Prevent off-screen re-renders during RoomView transitions while keeping subscription active */} + <ChatsStack.Screen name='RoomsListView' component={RoomsListView} options={{ freezeOnBlur: true }} />🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/stacks/InsideStack.tsx` at line 103, Add an inline comment above or on the same line as the freezeOnBlur: true option in the ChatsStack.Screen configuration for RoomsListView to explain the performance motivation. The comment should clarify that freezeOnBlur prevents unnecessary re-renders of the off-screen RoomsListView when navigating to RoomView, helping future maintainers understand why this optimization is present.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@app/stacks/InsideStack.tsx`:
- Line 103: Add an inline comment above or on the same line as the freezeOnBlur:
true option in the ChatsStack.Screen configuration for RoomsListView to explain
the performance motivation. The comment should clarify that freezeOnBlur
prevents unnecessary re-renders of the off-screen RoomsListView when navigating
to RoomView, helping future maintainers understand why this optimization is
present.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 01f9838b-b13e-4767-b546-d7471b452568
📒 Files selected for processing (1)
app/stacks/InsideStack.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: ESLint and Test / run-eslint-and-test
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions
Files:
app/stacks/InsideStack.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbersUse TypeScript with strict mode enabled
Files:
app/stacks/InsideStack.tsx
**/*.{js,jsx,ts,tsx,json}
📄 CodeRabbit inference engine (CLAUDE.md)
Use Prettier formatting with tabs, single quotes, 130 character line width, no trailing commas, and avoid arrow function parentheses
Files:
app/stacks/InsideStack.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Enforce ESLint rules from
@rocket.chat/eslint-configwith React, React Native, TypeScript, and Jest plugins
Files:
app/stacks/InsideStack.tsx
app/stacks/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Place navigation stacks in 'app/stacks/' directory (InsideStack for authenticated, OutsideStack for login/register, MasterDetailStack for tablets, ShareExtensionStack)
Files:
app/stacks/InsideStack.tsx
🧠 Learnings (1)
📚 Learning: 2026-04-30T17:07:51.020Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7274
File: app/lib/services/voip/MediaCallEvents.ts:0-0
Timestamp: 2026-04-30T17:07:51.020Z
Learning: In this Rocket.Chat React Native codebase, the ESLint rule `no-void: error` is enforced. When you see a promise returned from an async call that is not awaited (a “floating promise”), do not silence it with the `void somePromise()` pattern. Instead, handle the promise explicitly by attaching `.catch(...)` (or otherwise awaiting/handling the error) so unhandled-rejection risks are addressed in a way that satisfies the existing ESLint configuration.
Applied to files:
app/stacks/InsideStack.tsx
🔇 Additional comments (1)
app/stacks/InsideStack.tsx (1)
103-103: freezeOnBlur is a valid and supported option for native-stack screens in@react-navigation/native-stack@7.3.23.The configuration is correct and will prevent the RoomsListView from re-rendering when it loses focus, improving performance while maintaining subscription state since cleanup only happens on unmount, not blur.
Proposed changes
On phones, opening a room pushes RoomView over RoomsListView, but the list behind keeps rendering — every off-screen RoomItem re-renders during the transition, adding avoidable JS work to room open.
This sets
freezeOnBlur: trueon the RoomsListView screen in the phone Chats stack, so the list stops rendering while it's blurred (fully covered by RoomView) and thaws with the latest data on return.Tablet/master-detail is unaffected: there RoomsListView is rendered as drawer content, a separate path with no freeze. The WatermelonDB subscription stays alive while the screen is frozen (react-freeze keeps the component mounted) — only rendering is deferred and applied on thaw, so the list reflects any changes made while it was blurred.
Issue(s)
https://rocketchat.atlassian.net/browse/NATIVE-1291
How to test or reproduce
Screenshots
N/A — no visual change.
Types of changes
Checklist
Summary by CodeRabbit