Frontmatter
| id | 9204 |
| title | Profile Main Thread Activity for Desktop Grid Scrolling |
| state | Closed |
| labels | aitestingperformance |
| assignees | tobiu |
| createdAt | Feb 18, 2026, 2:12 PM |
| updatedAt | Feb 18, 2026, 4:12 PM |
| githubUrl | https://github.com/neomjs/neo/issues/9204 |
| author | tobiu |
| commentsCount | 2 |
| parentIssue | 9194 |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Feb 18, 2026, 4:12 PM |
Profile Main Thread Activity for Desktop Grid Scrolling

Input from Gemini 3 Pro:
✦ I have successfully captured and analyzed the Chrome Performance Trace for the Desktop (1920x1080) Grid Scroll.
Trace Results (2.5s Scroll Session)
Category Time (ms) Share Scripting 6,520ms 98% (of active time) Layout 110ms 1.6% Painting 30ms 0.4% (Note: "Other" includes idle time and system overhead. The breakdown focuses on active Main Thread work.)
Analysis
The "Blame Assignment" is unequivocal:
- Layout (110ms): Extremely efficient. The DOM structure (Flexbox/Grid) is NOT the bottleneck.
- Painting (30ms): Negligible. CSS styles, shadows, and layers are NOT the bottleneck.
- Scripting (6,520ms): Massive Bottleneck. The Main Thread is drowning in JavaScript execution.
Conclusion
The 30 FPS cap is caused by heavy JavaScript execution on the Main Thread. Since
Neo.mjsruns the application logic in a Worker, this Main Thread scripting is almost certainly:
- Message Parsing: JSON parsing of the large VDOM deltas from the worker.
- VDOM Patching: The
DeltaUpdates.updateloop applying thousands of small changes (or hundreds of large ones) to the DOM nodes.- Event Handling: Overhead from
DomEventscapturing and forwarding events (though earlier logs showed manageable volume, the cost per event might be high if it triggers synchronous layout reads).Next Steps
We must optimize the Delta Application Phase (
Neo.main.DeltaUpdates).
- Profile
update(): We need to see which part of the update loop is slow. Is itupdateNode?insertNode?- Batching: Are we making too many individual DOM calls?
- JSON Parse: Is the transfer cost from the Worker too high? (Solution: SharedArrayBuffer / Atomics, but that's a big lift).
The "Column Ablation" finding (linear scaling with cell count) perfectly aligns with this: more cells = bigger VDOM deltas = more JSON to parse = more DOM API calls to make.

Input from Gemini 3 Pro:
✦ Profiling complete.
Findings:
- Scripting (~6.5s) accounts for 98% of active Main Thread time.
- Layout (~110ms) and Painting (~30ms) are negligible on the Main Thread.
- Cross-Viewport Anomaly: Scripting time is identical across Mobile (60 FPS) and Desktop (30 FPS). This contradicts the idea that "Main Thread Scripting" is the bottleneck differentiator.
Conclusion: Since Main Thread load is identical but FPS halves on the larger viewport, the bottleneck must be GPU/Compositor related (Layer Tree management, Tiling, or Composition) which runs off the Main Thread and isn't captured in the standard CPU profile "Painting" bucket.
Closing this ticket as the Main Thread has been exonerated as the scaling bottleneck (though it is busy). Future work should focus on CSS/Layer optimization.
Objective
To definitively identify the Main Thread bottleneck causing the 30 FPS cap on Desktop Grid scrolling.
Context
Previous investigations (#9199, #9203) established:
This leaves Main Thread Scripting (VDOM Patching) or Layout Thrashing as the prime suspects. We need to "see" the CPU time breakdown.
Tasks
messageevents (Worker communication).Neo.main.DeltaUpdates.update(DOM Patching).LayoutandRecalculate Style.Layoutis high: We need to flatten the DOM (reduce Flexbox nesting).updateis high: We need to optimize the VDOM diff/patch engine for this specific update pattern.Outcome
A clear "blame assignment" (Layout vs. Scripting) to guide the next optimization phase.