Commite33f8560Recorded16 Jul 2026Repositorysigil-web-client
web-client: simplify reconcile-children
Message
Use map for the target node list and fold the empty->populated branch into the general moves path: first populate is now the same prune+moves flow with a preceding bulk clear (dropping possible pre-existing static markup), removing the duplicated append loop.
Changed
src/sigil/web/client.sgl | 64 +++++++++++++++++++++++++++++-----------------------------------
1 file changed, 29 insertions(+), 35 deletions(-)Diff
src/sigil/web/client.sglmodified
@@ -465,41 +465,35 @@
465
;; dropped nodes, then insert-before only the nodes whose position 466
;; actually changed. The unchanged common case makes zero DOM calls. 467
(define (web-client-reconcile-children! parent old-records ordered)−468
(let ((target (let collect ((rest ordered) (acc '()))−469
(if (null? rest)−470
(reverse acc)−471
(collect (cdr rest)−472
(cons (web-client-record-node (car rest)) acc))))))−473
(cond−474
;; populated -> empty: one bulk clear beats N removals.−475
((null? target)−476
(when (pair? old-records)−477
(wasm-dom-replace-children parent)))−478
;; empty -> populated (first populate of this parent): clear any−479
;; pre-existing content (e.g. static placeholder markup in a root−480
;; that was never rendered into) and append in order, exactly like−481
;; the old path did on initial render.−482
((null? old-records)−483
(wasm-dom-replace-children parent)−484
(for-each−485
(lambda (node) (wasm-dom-append-child parent node))−486
target))−487
(else−488
;; Drop old top-level nodes not carried into the new set, keeping−489
;; the still-attached nodes in their current DOM order.−490
(let ((current (let prune ((rest old-records) (acc '()))−491
(if (null? rest)−492
(reverse acc)−493
(let ((node (web-client-record-node (car rest))))−494
(if (memv node target)−495
(prune (cdr rest) (cons node acc))−496
(begin−497
(wasm-dom-remove-child parent node)−498
(prune (cdr rest) acc))))))))−499
(for-each−500
(lambda (op)−501
(wasm-dom-insert-before parent (car op) (cdr op)))−502
(web-client-child-moves current target)))))))+468
(let ((target (map web-client-record-node ordered)))+469
(if (null? target)+470
;; populated -> empty: one bulk clear beats N removals. (When both+471
;; sides are empty nothing is touched, so a childless element costs+472
;; no bridge call per render.)+473
(when (pair? old-records)+474
(wasm-dom-replace-children parent))+475
(begin+476
;; empty -> populated (first populate of this parent): clear any+477
;; pre-existing content first (e.g. static placeholder markup in+478
;; a root that was never rendered into), like the old path did on+479
;; initial render. The moves below then append every node.+480
(when (null? old-records)+481
(wasm-dom-replace-children parent))+482
;; Drop old top-level nodes not carried into the new set, keeping+483
;; the still-attached nodes in their current DOM order.+484
(let ((current (let prune ((rest old-records) (acc '()))+485
(if (null? rest)+486
(reverse acc)+487
(let ((node (web-client-record-node (car rest))))+488
(if (memv node target)+489
(prune (cdr rest) (cons node acc))+490
(begin+491
(wasm-dom-remove-child parent node)+492
(prune (cdr rest) acc))))))))+493
(for-each+494
(lambda (op)+495
(wasm-dom-insert-before parent (car op) (cdr op)))+496
(web-client-child-moves current target))))))) 497
498
(define (web-client-patch-children parent old-records new-values) 499
(let loop ((rest (web-client-normalize-children new-values))