@@ -408,13 +408,24 @@ class VDom extends Base {
408408 }
409409
410410 /**
411- * Neo.vdom.Helper will create ids for each vnode which does not already have one,
412- * so we need to sync them into the vdom.
411+ * Synchronizes state between the live VDOM (blueprint) and the incoming VNode (worker response).
412+ *
413+ * 1. **ID Synchronization (VNode -> VDOM):**
414+ * `Neo.vdom.Helper` automatically assigns dynamic IDs to any VNode that lacks one, as the
415+ * delta update engine requires unique IDs to target DOM nodes. These generated IDs are
416+ * synced back into the VDOM to ensure stability and persistent referencing for future updates.
417+ *
418+ * 2. **Scroll State Synchronization (Bidirectional):**
419+ * - **Preservation (VDOM -> VNode):** Ensures that the latest scroll position captured on the
420+ * Main Thread (stored in VDOM) overrides potentially stale state returning from the Worker.
421+ * - **Rehydration (VNode -> VDOM):** Ensures that new VDOM trees (e.g., from Functional Components)
422+ * inherit the persistent scroll state from the existing VNode.
423+ *
413424 * @param {Neo.vdom.VNode } vnode
414425 * @param {Object } vdom
415426 * @param {Boolean } force=false The force param will enforce overwriting different ids
416427 */
417- static syncVdomIds ( vnode , vdom , force = false ) {
428+ static syncVdomState ( vnode , vdom , force = false ) {
418429 if ( vnode && vdom ) {
419430 vdom = VDom . getVdom ( vdom ) ;
420431
@@ -435,6 +446,24 @@ class VDom extends Base {
435446 }
436447 }
437448
449+ // 1. Rehydration (vnode -> vdom)
450+ // Used by Functional Components (vdom is new)
451+ if ( Neo . isNumber ( vnode . scrollTop ) && ! Neo . isNumber ( vdom . scrollTop ) ) {
452+ vdom . scrollTop = vnode . scrollTop
453+ }
454+ if ( Neo . isNumber ( vnode . scrollLeft ) && ! Neo . isNumber ( vdom . scrollLeft ) ) {
455+ vdom . scrollLeft = vnode . scrollLeft
456+ }
457+
458+ // 2. Preservation (vdom -> vnode)
459+ // Used by Classic Components (vdom is source of truth via capture)
460+ if ( Neo . isNumber ( vdom . scrollTop ) ) {
461+ vnode . scrollTop = vdom . scrollTop
462+ }
463+ if ( Neo . isNumber ( vdom . scrollLeft ) ) {
464+ vnode . scrollLeft = vdom . scrollLeft
465+ }
466+
438467 if ( childNodes ) {
439468 cn = childNodes . map ( item => VDom . getVdom ( item ) ) ;
440469 // The vnode.childNodes array is already filtered by the worker.
@@ -448,7 +477,7 @@ class VDom extends Base {
448477
449478 for ( ; i < len ; i ++ ) {
450479 if ( vnode . childNodes ) {
451- VDom . syncVdomIds ( vnode . childNodes [ i ] , cn [ i ] , force )
480+ VDom . syncVdomState ( vnode . childNodes [ i ] , cn [ i ] , force )
452481 }
453482 }
454483 }
0 commit comments