perf(ui): lazy-load markdown and defer diff rendering#215
perf(ui): lazy-load markdown and defer diff rendering#215shantur merged 8 commits intoNeuralNomadsAI:devfrom
Conversation
|
Hi @pascalandr Thanks for the PR Would you be able to explain the issue that this PR solves? Thanks |
|
This PR reduces startup and initial-render work in the UI by moving markdown rendering and diff/highlighting code off the initial bundle path. Before this change, the app paid the markdown + diff viewer cost eagerly even when the user had not opened content that needed those renderers yet. The result was a heavier initial UI load and slower perceived startup. This PR lazy-loads those paths and slims the diff highlighter dependency so we only pay that cost when the user actually opens markdown or diff-heavy content. |
|
Validate the issue if its present Be the gatekeeper and check if this PR fixes what it says, and does that keeping the coding standards |
|
Looked through the PR with the “gatekeeper” lens: does it fix the stated startup/perf issue, any regressions, any hidden scope. What I understand the issue to be
Does this PR address that?
Validation (local)
Potential regressions / behavior changes
Hidden features / scope creep
Suggestions (tight scope)
-- |
|
What is packages/ui/src/lib/git-diff-lowlight.ts doing the PR ? |
|
What it does in this PR
How it’s wired
Why it exists
Tradeoff
-- |
|
@pascalandr - Can you please review the "Potential regressions / behavior changes" mentioned |
|
That was a fair callout. Markdown rendering no longer throws when a text part has no I also kept the Monaco/right-panel chunk-splitting work out of this base PR. That part now lives in the stacked follow-up on my fork (
The remaining behavior change is the expected deferred-render tradeoff: markdown may initially render with fallback HTML and fenced code highlighting can become progressively enhanced once the renderer/language data finishes loading, but the hard crash case is now addressed. |
|
Check the current PR state |
|
Current PR state (local checkout) What I’m checking
State
Regression status
Quick verification
Note
-- |
16ee70f to
f1696aa
Compare
|
Updated this to target dev properly. I rebuilt the branch on top of dev, removed the unrelated auth, Electron, and server changes from the diff, and kept only the markdown and diff loading work in this PR. I also reran the UI build on the rebuilt branch. |
|
Updated this again after the dev retarget work. I rebuilt the branch cleanly on top of dev, force-pushed it, and kept the diff limited to the markdown and diff rendering work only. I also restacked the follow-up branch on top of this refreshed base. |
|
|
Re-ran PR checks on current branch head. What I understood
Results (local)
Notable build warnings (unchanged)
Branch position vs base
-- |
|
I want you to perform the gatekeeper checks for latest PR state
|
|
Gatekeeper pass on latest PR state (current HEAD) focusing on regressions + implementation quality. What I’m checking / assumptions
Current state
Does it still fix the stated issue?
Regression watchlist (what could break)
Implementation quality notes (what looks good)
Suggestions (tight scope; not required for merge)
No hidden features spotted
-- |
|
I took the latest gatekeeper pass into account. I applied the actionable follow-up from that review in this branch: the Git Changes overlay aria label now goes through the existing translation key instead of staying hardcoded. The other notes in the latest bot pass looked non-blocking to me:
So I kept this PR focused on the markdown and diff loading changes themselves. |
|
I reshuffled the split a bit. I moved the Monaco-specific secondary viewer chunking into this base branch, since it directly completes the lazy markdown and diff story here. The remaining right panel, picker, and tool-call chunking work stays in Pagecran#1, which now targets dev directly instead of stacking on top of this branch. |
|
I want you to perform the gatekeeper checks for latest PR state check for regressions |
|
Gatekeeper checks (latest PR state as of current HEAD) What I understood
Current PR state (local)
Verification
Does it still match PR intent?
Regression watchlist
Coding standards / hygiene
Suggestions (non-blocking)
-- |
|
Give me detailed analysis for
|
|
Detailed analysis on the two gatekeeper callouts.
What changed
How highlighting is selected at runtime (important)
What “reduced coverage” means in practice
Where this shows up for CodeNomad
Mitigations / knobs already in the adapter
What I’d watch for (regression signals)
If you want a “better” implementation (tradeoffs)
What it does
Why this usually helps
Concrete output from the current build (so we’re not hand-wavy)
What “changing chunk boundaries” impacts (deploy/PWA)
Regression watchlist
If you want a “better” implementation (optional)
-- |
|
Can you list the languages supported pre and post PR changes |
1 similar comment
|
Can you list the languages supported pre and post PR changes |
|
Language support for diff syntax highlighting (the
Impact on our file-extension -> language inference (
Post-PR registered languages (38)Pre-PR bundled highlight.js languages (192)-- |
|
@pascalandr - Is reduction in languages on purpose? |
|
Yes, it was intentional, as a secondary bundle-size/load-time optimization, |
|
Yes please let's not reduce the language support, I am ready to merge this as soon as its done |
|
Removed the local replacement, so diff highlighting now keeps the upstream language coverage. The PR is back to the lazy-loading / deferred rendering changes only, and I reran UI typecheck + build on this updated branch. |
|
Removed the local lowlight replacement, so diff highlighting keeps the upstream language coverage now. The branch only keeps the lazy-loading / deferred rendering changes, and I reran UI typecheck + build on it. |
|
I want you to perform the gatekeeper checks for latest PR state check for regressions |
|
Gatekeeper checks on latest PR state (after upstream diff-highlighting coverage was restored). What I understood
Current state
Verification
Does it still do what the PR claims?
Regression watchlist
Implementation quality / standards
Non-blocking suggestions
-- |
…255) ## Thanks for contributions - PR [#249](#249) "feat(speech): add prompt voice input" by [@shantur](https://github.com/shantur) - PR [#243](#243) "feat(i18n): Hebrew locale + full RTL support" by [@MusiCode1](https://github.com/MusiCode1) - PR [#241](#241) "feat(lazy loading): Implement virtual list with virtua" by [@pixellos](https://github.com/pixellos) - PR [#240](#240) "fix(tauri): force Windows process tree shutdown" by [@pascalandr](https://github.com/pascalandr) - PR [#239](#239) "perf(ui): split right panel and secondary viewer chunks" by [@pascalandr](https://github.com/pascalandr) - PR [#238](#238) "perf(ui): defer locale and overlay bundles" by [@pascalandr](https://github.com/pascalandr) - PR [#236](#236) "Suppress OS notifications for subagent (child) sessions" by `@app/codenomadbot` - PR [#235](#235) "fix(ui): unwrap pasted placeholders in slash commands" by `@app/codenomadbot` - PR [#232](#232) "fix(tauri): stop CLI process group on exit" by `@app/codenomadbot` - PR [#229](#229) "feat(ui): add RTL support for Hebrew/Arabic text" by [@MusiCode1](https://github.com/MusiCode1) - PR [#227](#227) "fix(tauri): improve Windows desktop runtime behavior" by [@pascalandr](https://github.com/pascalandr) - PR [#226](#226) "fix(tauri): restore desktop menu controls and fullscreen shortcut" by [@pascalandr](https://github.com/pascalandr) - PR [#225](#225) "fix(tauri): restore external links in the folder picker" by [@pascalandr](https://github.com/pascalandr) - PR [#224](#224) "fix(tauri): sync server UI bundle during prebuild" by [@pascalandr](https://github.com/pascalandr) - PR [#215](#215) "perf(ui): lazy-load markdown and defer diff rendering" by [@pascalandr](https://github.com/pascalandr) ## Highlights - **Voice-first conversations**: Start prompts with voice input, configure speech behavior from settings, and listen back to assistant responses with message playback and conversation playback controls. - **A complete Hebrew + RTL experience**: CodeNomad now ships with a full Hebrew locale and much broader right-to-left support, making the app feel natural for Hebrew users while improving Arabic text rendering too. - **A much faster experience in long chats**: The new virtualized message list, deferred markdown and diff rendering, and more selective loading for heavy UI surfaces make large sessions feel noticeably smoother. ## What's Improved - **More flexible speech controls**: Speech settings and playback modes now adapt better to different browsers and platform capabilities. - **Cleaner prompt workflow**: The prompt includes a quick clear action, a simpler recording indicator, and a more polished mic control layout. - **Faster startup and lighter heavy views**: Locale bundles, overlays, right-panel viewers, picker flows, markdown, and diff surfaces all load more lazily to reduce upfront UI work. - **Less notification spam**: Subagent sessions no longer fire OS notifications, so important interruptions are easier to notice. - **Better RTL behavior across the whole interface**: Session names, tool outputs, markdown blocks, file views, selectors, and layout controls behave more consistently in right-to-left contexts. ## Fixes - **More reliable Windows desktop behavior**: Process cleanup is stronger during app shutdown, background CLI process trees are terminated more reliably, desktop identity/metadata is aligned more cleanly, and stray console windows are hidden during startup and exit. - **Cleaner shutdown on macOS and Linux**: Desktop quit/close now stops the spawned CLI process group more reliably, reducing leftover background processes after exit. - **Restored desktop actions**: External links in the folder picker work again, and the desktop View/Window controls plus the fullscreen shortcut are back. - **More stable streaming and scrolling**: Reasoning streams stay pinned more consistently, follow behavior is less jumpy, spacing is cleaner in virtualized conversations, and session switching retains position more smoothly. - **Safer slash command pasting**: Pasted placeholders are resolved correctly before slash commands run, so long pasted inputs behave like normal prompts. - **More dependable desktop packaging**: Tauri prebuild now refreshes the server UI bundle correctly, which avoids packaged desktop builds picking up stale UI assets. - **Clearer speech compatibility handling**: Streaming playback limitations are surfaced more cleanly instead of failing in a confusing way. ### Contributors - [@pascalandr](https://github.com/pascalandr) - [@MusiCode1](https://github.com/MusiCode1) - [@pixellos](https://github.com/pixellos)
Summary
Follow-ups
Testing