⚡ Bolt: Prevent O(N) re-renders in high-frequency WebSocket components#146
⚡ Bolt: Prevent O(N) re-renders in high-frequency WebSocket components#146primoscope wants to merge 1 commit intomainfrom
Conversation
- Extract inline list item render logic in `ProgressPanel` and `LogPanel` into separate `DownloadItem` and `LogItem` components. - Wrap extracted components in `React.memo` to prevent unnecessary re-renders. - Use a custom equality function for `DownloadItem` to perform shallow comparison of primitive fields safely. - Add an `id` field to `LogMessage` and generate a stable client-side unique ID upon receiving log messages, using this ID as the React `key` instead of the array index. - Move static formatting and coloring functions (`formatSpeed`, `formatETA`, `getStatusColor`, `getLogColor`) outside of component bodies to avoid recreating them on every render. - Added explanatory inline comments. Co-authored-by: dzp5103 <214723817+dzp5103@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
💡 What:
Extracted the list item rendering logic in
ProgressPanel(for downloads) andLogPanel(for logs) into their own components (DownloadItemandLogItem), wrapped them inReact.memo, and provided stable keys (by assigning a unique client-sideidto log messages). Static helper functions were also moved out of the render bodies.🎯 Why:
Because these components subscribe to high-frequency WebSocket streams, updating a single item in the
downloadsor appending a single item to thelogsarray would previously cause the entire array of inline elements to re-render in React. This is an O(N) rendering bottleneck that degrades UI performance as the list sizes grow.📊 Impact:
Prevents O(N) re-renders across the dashboard when a new log arrives or a download's progress ticks. This significantly reduces main-thread blocking and memory churn, keeping the UI smooth even with dozens of active downloads and thousands of log entries streaming in.
🔬 Measurement:
Use the React Profiler to record interactions while downloads are active. You will see that only the individual
DownloadItemcomponents whose progress actually changed are re-rendering, rather than the entire list. For logs, only the newly appendedLogItemmounts; previously rendered logs will not re-render.PR created automatically by Jules for task 17722708389685146381 started by @dzp5103