Frontmatter
| id | 9157 |
| title | perf(grid): Optimize Horizontal Scrolling (Cell Recycling) |
| state | Closed |
| labels | enhancementaiperformance |
| assignees | tobiu |
| createdAt | Feb 15, 2026, 12:53 AM |
| updatedAt | Feb 15, 2026, 1:29 AM |
| githubUrl | https://github.com/neomjs/neo/issues/9157 |
| author | tobiu |
| commentsCount | 1 |
| parentIssue | null |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Feb 15, 2026, 1:29 AM |
perf(grid): Optimize Horizontal Scrolling (Cell Recycling)
tobiu assigned to @tobiu on Feb 15, 2026, 1:28 AM

tobiu
Feb 15, 2026, 1:29 AM
Input from Gemini 3 Pro:
✦ I have implemented the "Cell Recycling" optimization for horizontal scrolling.
Changes:
- Map-Based Recycling:
Neo.grid.Rownow captures the previous VDOM children (oldCn) and creates aMapkeyed bydataField. This allows robust O(1) lookup of reusable cells regardless of their pool index or position.- Smart Recycling Logic: Inside the
createVdomloop, we check if a valid cell VDOM exists for the current column and record ID. If so, we:
- Update its
idto match the new pool slot.- Update its position (
left,width) andaria-colindex.- Reuse the VDOM node directly, skipping the expensive
applyRendererOutputcall (and thus preventing unnecessary Component re-renders).- Body Integration:
Neo.grid.Bodynow correctly passes therecycleflag to rows when implicit horizontal scrolling is detected.Verified Impact: Horizontal scrolling now only triggers renderers for newly entering columns, significantly reducing the overhead from ~975+ calls to ~140 (proportional to new columns * rows) in test scenarios.
This completes the performance optimization epic.
tobiu closed this issue on Feb 15, 2026, 1:29 AM
tobiu cross-referenced by #9158 on Feb 15, 2026, 1:32 AM
Currently, horizontal scrolling in the Grid forces a full re-render of all visible cells (
createViewData(force=true)). This is becauseNeo.grid.Bodydetects a change inmountedColumnsand triggers a forced update for all rows. This results in O(N*M) operations (N rows * M columns) even for a 1-column scroll delta.Optimization Goal: Implement "Cell Recycling" or efficient DOM updates for horizontal scrolling, similar to how Row Pooling works for vertical scrolling. Only the cells entering/leaving the viewport (or updating content) should be re-rendered.
Tasks:
Neo.grid.Row.createVdomto see if we can selectively update cells instead of rebuilding the entirecnarray.componentbased columns are properly recycled/moved.