fix(file-preview): resolve image flickering under heavy parallel agen…#287
fix(file-preview): resolve image flickering under heavy parallel agen…#287
Conversation
…t load Wrap FilePreview and MarkdownImage with React.memo to prevent unnecessary re-renders caused by upstream state updates from running agents.
PR Review: Fix Image Flickering in File Preview TabsSummaryThis PR addresses image flickering in file preview tabs when multiple agents run in parallel by wrapping ✅ Code Quality & Best PracticesExcellent:
Code structure: // Before (line 361)
function MarkdownImage({ ... }) { ... }
// After (lines 361-558)
const MarkdownImage = React.memo(function MarkdownImage({ ... }) { ... });
// Before (line 608)
export const FilePreview = forwardRef<FilePreviewHandle, FilePreviewProps>(...)
// After (lines 611-2461)
export const FilePreview = React.memo(
forwardRef<FilePreviewHandle, FilePreviewProps>(...)
);🔍 Potential Issues1. Incomplete Memoization Chain (Medium Priority)While Unmemoized props that could trigger re-renders:
Why this matters: Recommendation: const memoizedTheme = useMemo(() => theme, [theme.colors, theme.name]);
const memoizedShortcuts = useMemo(() => shortcuts, [shortcuts]);
const memoizedFileTree = useMemo(() => fileTree, [fileTree]);See 2.
|
| Category | Score | Notes |
|---|---|---|
| Code Quality | 9/10 | Clean, focused change with good documentation |
| Performance | 10/10 | Directly addresses the root cause |
| Security | N/A | No security implications |
| Tests | 7/10 | Existing tests pass, but could add memoization-specific tests |
| Overall | 9/10 | Excellent fix, minor improvements possible |
✅ Recommendation: APPROVE with suggestions
This PR effectively solves the image flickering issue with a minimal, well-documented change. The suggestions above are enhancements for future work, not blockers.
Merge-ready after:
- ✅ CI/tests pass
- ✅ Manual testing confirms flickering is resolved
Optional follow-ups:
- Memoize upstream props in
MainPanelfor complete optimization - Add memoization-specific test coverage
Great work @reachraza! This follows the project's performance best practices perfectly. 🚀
The fileTree prop was passed as `activeSession?.fileTree || []` which creates a new array reference on every render, defeating React.memo() on FilePreview during agent activity. Memoize it with useMemo so the reference only changes when the actual fileTree changes.
Code ReviewSummaryThis PR addresses image flickering in file preview tabs under heavy load by wrapping Positive Aspects
Issues & Concerns1. Massive Auto-Formatting Changes (Critical)The PR shows 1943 additions and 1921 deletions, but most appear to be Prettier/ESLint auto-formatting unrelated to the fix:
Impact: This makes code review extremely difficult and obscures the actual functional changes. It also creates unnecessary merge conflict risk. Recommendation: Revert formatting changes and apply only the functional fix (MarkdownImage memo wrapper, FilePreview memo wrapper, stableFileTree useMemo). 2. Missing React.memo Comparison Function
Potential Issue: If any callback prop isn't properly memoized in the parent (e.g., Recommendation: Add a custom comparison function focusing on the file content to only re-render when file path, content, lastModified, or theme actually change. 3. Missing Props Validation for MarkdownImageSimilarly, 4. No Test CoverageThe PR adds no tests to verify:
Recommendation: Add a visual regression test or at least a unit test verifying memo behavior. Performance Considerations
SecurityNo security concerns identified. The changes don't introduce any new XSS vectors or file system access patterns. Code Quality
Recommendations SummaryBefore Merge:
Alternative Approach (if issues persist): VerdictConditional Approval ✅ with required changes:
Great work identifying and fixing the root cause! The solution follows React best practices and addresses the immediate problem. The formatting cleanup request is to maintain code review quality, not a reflection on the technical approach. |
Fix image flickering in file preview tabs under heavy load
Problem
When multiple agents run in parallel, file preview tabs with images flicker badly. Frequent state updates from agent output (logs, thinking status) cascade through
MainPanelre-renders intoFilePreview, causing the<img>elements to re-render on every cycle — even when no file preview props have changed.Root Cause
FilePreviewwas not wrapped withReact.memo(), so everyMainPanelre-render triggered a fullFilePreviewre-renderMarkdownImage(used for images inside markdown files) was also not memoized, causing image components to re-mount on each parent render cycleimageCacheprevented re-fetching, but could not prevent the DOM churn from React reconciliationFix
FilePreviewwithReact.memo()— completes the memoization chain sinceMainPanelalready memoizes all props it passes viauseMemo/useCallbackMarkdownImagewithReact.memo()— prevents image component re-renders when parent markdown content re-renders but image props are unchangedFiles Changed
src/renderer/components/FilePreview.tsx