⚡ Bolt: [Performance] Optimize Map Editor Diffs (O(N²) to O(N))#157
⚡ Bolt: [Performance] Optimize Map Editor Diffs (O(N²) to O(N))#157xb1g wants to merge 1 commit into
Conversation
- Replaced `.some()` and `.find()` array operations inside iterative loops (`.filter`, `.forEach`) with pre-computed `Set` and `Map` lookups. - Applied optimization to diffing nodes, paths (using composite `source-destination` string keys), content, assessments, and quiz questions. - Time complexity of these updates reduced from O(N²) to O(N), resolving significant CPU overhead when processing large map payloads in `app/map/[id]/edit/edit-page-client.tsx`. Co-authored-by: xb1g <70068561+xb1g@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. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
d62fd79 to
77523a4
Compare
|
Unable to deploy a commit from a private repository on your GitHub organization to the wachaa1319's projects team on Vercel, which is currently on the Hobby plan. In order to deploy, you can:
To read more about collaboration on Vercel, click here. |
There was a problem hiding this comment.
Pull request overview
This PR optimizes the Map Editor’s “generate batch update” diffing logic to reduce CPU time during saves on large learning maps by replacing nested array scans (.some() / .find() inside loops) with precomputed Set/Map lookups.
Changes:
- Reworked node diffing to use
Set/Mapfor delete/create/update detection. - Reworked path diffing to use
Setlookups based on a composite(source_node_id, destination_node_id)key. - Reworked content, assessment, and quiz-question diffing to use
Set/Maplookups per node/assessment.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| app/map/[id]/edit/edit-page-client.tsx | Replaces O(N²) diffing patterns with Set/Map lookups to reduce save-time UI thread blocking on large maps. |
| .jules/bolt.md | Documents the performance pattern change and rationale for future reference. |
| **Learning:** Found multiple instances where `.filter(x => !array.includes(x))` was being used, which is O(N^2). | ||
| **Action:** Replace `array.includes` with `Set.has` when filtering large arrays to improve performance. | ||
|
|
||
| ## 2025-02-28 - [Replaced Array .find() and .some() inside loops with O(1) Maps and Sets] |
0b52ea4 to
dfa7959
Compare
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ❌ Deployment failed View logs |
web | dfa7959 | May 11 2026, 06:20 PM |
💡 What:
Optimized the diffing algorithms used to detect changes in Maps during saving in
app/map/[id]/edit/edit-page-client.tsx. The previous implementation iterated through elements comparing against other arrays utilizing.some()and.find(). The new implementation utilizes pre-calculatedMaps andSets before beginning the iteration loops. For Paths, it implements a composite string key utilizing${source_node_id}-${destination_node_id}to represent unique edges.🎯 Why:
Using
.some()or.find()inside a.filter()or.forEach()loop inherently produces nested iteration resulting in O(N²) time complexity. On maps with large amounts of nodes, assessments, and connections, this causes severe UI lag and locks up the main browser thread during the calculation phase. Using Sets and Maps ensures O(1) key/value lookups resulting in O(N) total complexity.📊 Impact:
Reduces the time complexity of diff detection from O(N*M) to O(N) where N and M are the sizes of the current and initial elements. Resolves frontend thread-blocking when generating the batch update payload for large learning maps.
🔬 Measurement:
Run the existing test suite and
lint. The logical output remains completely identical. Performance measurements can be verified locally using React Profiler or Chrome DevTools while saving an extremely large learning map (e.g. >100 nodes/connections) before and after the change; execution time in thesaveMapdiffing phase should be consistently shorter.PR created automatically by Jules for task 1696303809515594833 started by @xb1g