Skip to content

⚡ Bolt: [performance improvement] Optimize high-frequency WebSocket renders#134

Draft
primoscope wants to merge 1 commit intomainfrom
bolt-websocket-render-optimization-7171515410301489171
Draft

⚡ Bolt: [performance improvement] Optimize high-frequency WebSocket renders#134
primoscope wants to merge 1 commit intomainfrom
bolt-websocket-render-optimization-7171515410301489171

Conversation

@primoscope
Copy link
Copy Markdown
Owner

💡 What:

  • Extracted static helper functions (formatSpeed, getStatusColor, etc.) outside of component bodies to prevent memory churn on re-renders.
  • Created DownloadItem and LogItem components wrapped in React.memo().
  • Implemented arePropsEqual for DownloadItem to ensure API polling does not force unnecessary re-renders when data is identical.
  • Added a stable generated ID (Date.now() + Math.random()) for incoming log WebSocket messages instead of using the array index as the React key.
  • Updated .jules/bolt.md with critical learnings on high-frequency WebSocket rendering.

🎯 Why:
The application relies heavily on high-frequency WebSocket updates (progress bars, download speeds, real-time logs) and interval polling backups. Previously, an update to a single download item or the appending of a single log message would force React to re-render the entire list of components (O(N) re-renders). This severely impacts performance, causes UI stuttering during heavy downloads, and increases memory usage.

📊 Impact:
Reduces high-frequency list rendering cost from O(N) to O(1) for both the ProgressPanel and LogPanel. Memory allocation is reduced as helper functions are no longer repeatedly created inside the render loop.

🔬 Measurement:

  1. Build the frontend (cd frontend && pnpm run build) and start the application.
  2. Queue multiple simultaneous downloads.
  3. Observe React DevTools Profiler: the ProgressPanel and LogPanel will no longer highlight full-list re-renders on every incoming WebSocket frame; only the specific DownloadItem or newly appended LogItem will render.

PR created automatically by Jules for task 7171515410301489171 started by @dzp5103

…enders

- Extracted static helper functions in ProgressPanel and LogPanel
- Wrapped DownloadItem and LogItem in React.memo()
- Added a custom equality function for DownloadItem polling stability
- Replaced array index with stable generated IDs for LogItem keys
- Added critical learnings journal to .jules/bolt.md

Co-authored-by: dzp5103 <214723817+dzp5103@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown

👋 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 @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant