Frontmatter
| id | 9401 |
| title | Performance: Proxy Getter Hoisting in Grid Row & Array Slice Optimization |
| state | Closed |
| labels | enhancementaiperformance |
| assignees | tobiu |
| createdAt | Mar 8, 2026, 10:40 PM |
| updatedAt | Mar 8, 2026, 10:59 PM |
| githubUrl | https://github.com/neomjs/neo/issues/9401 |
| author | tobiu |
| commentsCount | 1 |
| parentIssue | null |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Mar 8, 2026, 10:59 PM |
Performance: Proxy Getter Hoisting in Grid Row & Array Slice Optimization
tobiu assigned to @tobiu on Mar 8, 2026, 10:59 PM

tobiu
Mar 8, 2026, 10:59 PM
Input from Gemini 3.1 Pro:
✦ Task Completed:
- Array Slice Optimization: Replaced the legacy
[...value]spread operator with the native V8 fast-pathvalue.slice()inside theNeo.mjsreactive config getter interceptor. This speeds up all framework array clones (e.g.items,columns,selectedRows).- Proxy Getter Hoisting: Refactored
src/grid/Row.mjs:createVdom()to destructure all neededgridBodyandgridContainerreactive configs once before the column loops.- Param Passing: Updated
applyRendererOutput()to accept acacheobject containing these hoisted values, completely bypassing thousands of proxy intercepts and shallow array clones that were previously triggered on every single cell render during grid scrolling.
tobiu closed this issue on Mar 8, 2026, 10:59 PM
Problem: Profiling the App Worker during fast grid scrolling reveals that the reactive Config getters (
Neo.mjs:348andBase.mjs:971) consume a massive17.4%of total self-time.A significant portion of this overhead comes from
src/grid/Row.mjs. DuringcreateVdom, the Row iterates over every column cell and callsapplyRendererOutput. InsideapplyRendererOutput, it queriesme.parent,me.parent.parent,gridBody.store,gridBody.selectedCells, andgridBody.colspanField.Because these are reactive array/object configs, querying them inside a 1,500-iteration hot loop triggers thousands of proxy intercepts and forces the framework to shallow-clone arrays (
selectedCells) thousands of times per frame.Furthermore, the default array cloning mechanism in
Neo.mjsuses[...value], which is inherently slower than the nativevalue.slice().Proposed Solution:
Row.mjs:createVdom, destructure all neededgridBodyandgridContainerproperties exactly once. Pass these stable references down intoapplyRendererOutputto completely bypass the getter proxy in the hot loop.Neo.mjsconfig getter trap, replace the legacy array clone logicvalue = [...value]withvalue = value.slice()for faster native array copies.