Frontmatter
| id | 9108 |
| title | Grid Body fast path fails to update Row mounted state, breaking OffscreenCanvas recovery |
| state | Closed |
| labels | bugai |
| assignees | tobiu |
| createdAt | Feb 12, 2026, 12:28 AM |
| updatedAt | Feb 12, 2026, 12:56 AM |
| githubUrl | https://github.com/neomjs/neo/issues/9108 |
| author | tobiu |
| commentsCount | 1 |
| parentIssue | 9106 |
| subIssues | [] |
| subIssuesCompleted | 0 |
| subIssuesTotal | 0 |
| blockedBy | [] |
| blocking | [] |
| closedAt | Feb 12, 2026, 12:56 AM |
Grid Body fast path fails to update Row mounted state, breaking OffscreenCanvas recovery

Input from Gemini 3 Pro:
✦ Fixed by removing the
onStoreLoadfast path optimization insrc/grid/Body.mjs.Rationale: The fast path (clearing DOM via
textContent = ''when store count is 0) was a legacy optimization designed before the Row Pooling architecture. With the current Fixed-DOM-Order strategy, this optimization became harmful: it destroyed the DOM nodes that pooled rows relied on, severing the connection betweenOffscreenCanvascomponents and their worker threads.By removing the fast path, clearing the grid (0 items) now efficiently updates the pooled rows to be hidden (
display: none) instead of destroying them. This preserves the DOM nodes and the Component instances, ensuring thatOffscreenCanvasconnections remain active for when data is reloaded, thus fixing the reconnection issue without requiring complex "healing" logic.Note: Row Pooling ensures that this operation remains O(PoolSize) efficient, not O(TotalRecords).
The
Neo.grid.Body#onStoreLoadmethod has a "fast path" for clearing the grid when the store has 0 items (e.g., due to filtering). This path directly clears the VDOM children (vdomRoot.cn = []) and the real DOM (textContent: '') to avoid expensive VDOM diffing.However, this bypasses the standard lifecycle updates for the pooled
Rowcomponents. They remain inme.itemswithmounted: true, even though they are physically removed from the DOM.When the store reloads with data, these
Rowcomponents are re-added to the VDOM. Since theirmountedconfig is stilltrue, theafterSetMountedhook is not triggered. This prevents child components likeOffscreenCanvas(used in Sparklines) from triggering their reconnection logic ("healing"), causing charts to disappear.Proposed Fix:
onStoreLoad(fast path): Explicitly setmounted = falsefor allRowitems.createViewData: Explicitly ensuremounted = truefor allRowitems if the Body itself is mounted.This synchronizes the component state with the physical DOM state while preserving the performance benefits of the fast path.