perf(mobile): prepare word diffs for visible rows - #9699
Conversation
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 0184829. Configure here.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR changes the production mobile diff-rendering pipeline from eager all-row word matching to asynchronous, visibility-scoped computation with new JS-to-native patch state on both Android and iOS. The cross-platform lifecycle, caching, cancellation, and delayed rendering behavior make this more than a small isolated performance tweak. You can add or adjust custom eligibility rules. Learn more. |

Native release hold
Hold this PR for a compatible native release. It changes the iOS and Android review module.
Mobile prepared word highlights for every changed line before showing a large diff. Prepare source rows first, then compute word ranges for visible replacement pairs. Indexing, skipped rows, and word matching yield during long requests. Keep word work independent of syntax highlighting and send ranges through the existing native setter. Android reports source row indexes after file collapse.
Mark rows complete only after native accepts their patch. Retain the last visible range when highlights reset in the same thread and section.
Validation:
Measurements used Node 24.20.0. The original fixture used two warmups and six samples. The larger scan checks used one sample each. They exclude native decode and drawing. No local native build, browser, or device testing. Native release and device verification remain required. Existing line-length and coverage rules stay intact.
Refs #9661.
Created with GPT-6 Astra (preview) in Codex.
Note
Medium Risk
Touches iOS/Android review rendering and async patch ordering; incorrect stale-patch handling could show wrong or missing word highlights, but no auth or data-path changes.
Overview
Defers word-level diff highlighting so large reviews no longer compute every deletion/addition pair up front. Row preparation drops embedded
wordDiffRanges; a newcomputeVisibleNativeReviewWordDiffRangespath indexes pairs once (with yield/cancel budgets), matches only the visible window (plus overscan), respects collapsed files, and caches completed pairs.Streams ranges to native separately from syntax tokens.
useNativeReviewDiffHighlightingruns word work in its own effect, sendswordDiffRangesByRowIdthrough the existing token patch bridge (wordDiffRangesPatchJson/setTokensPatchJson), and marks rows complete only after native dispatch viaonWordDiffRangesPatchSent. Highlight resets clear native word state but keep the last scroll range within the same thread/section (contentResetKeyvstokensResetKey).iOS and Android review modules merge patched ranges into drawing state, fall back to row JSON ranges, and report source row indexes in visible-range debug events so JS range requests stay aligned when files are collapsed. Tests add
react-test-renderercoverage for delayed patches and scroll/reset behavior.Reviewed by Cursor Bugbot for commit 166f5fa. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Compute word diffs asynchronously for visible rows only in mobile review diff
setTokensPatchJsonbridge command, with a delivery acknowledgement callback that excludes already-delivered row IDs from future requestssourceIndexto parsedDiffRowmodels so visible-range debug events report original payload row indexes rather than laid-out indexesprepareFileRowsin nativeReviewDiffAdapter.ts no longer mutates rows with computed word ranges; any out-of-tree caller relying onDiffRowcontaining pre-computed word ranges at construction time will not find themMacroscope summarized 166f5fa.