Skip to content

Conversation

TrevorBurnham
Copy link

Fixes #1888

This PR introduces a fast path for clearing all children from a parent node in O(n) time and wires it into hot code paths (innerHTML, textContent, replaceChildren, ShadowRoot.setHTMLUnsafe, and Document.open). It also optimizes cleanup in Node#[PropertySymbol.cloneNode] using the same technique. The change preserves observable behavior and MutationObserver semantics while significantly reducing time and allocations for large subtree clears.

Motivation

Several core DOM APIs in happy-dom clear a node by repeatedly calling removeChild(childNodes[0]) in a loop. Each removal from index 0 shifts the array, leading to O(n^2) behavior and extra GC pressure for large trees. This PR replaces those loops with a single-pass algorithm.

Design overview

  • New utility: ParentNodeUtility.clearChildren(parent)

    • Detaches and cleans all children in a single sweep.
    • Preserves NodeList reference identity by truncating arrays (length = 0) rather than reassigning them.
    • Clears elementArray in one step.
    • Reproduces the same sequence of childList MutationRecords that the previous loops emitted, matching previousSibling and nextSibling expectations.
    • Ensures correct lifecycle transitions (connected/disconnected) and cache invalidations.
    • Unobserves subtree mutation observers from removed subtrees as before.
  • Node#[PropertySymbol.cloneNode] cleanup

    • Replaces the previous while (childNodes.length) removeChild(childNodes[0]) pattern with a local fast-detach that snapshots children, truncates arrays (length = 0), and then clears parent links/cache and dispatches disconnects per child.

This commit replaces several removeChild loops with O(n^2) performance
characteristics with an O(n) "fast-detch" algorithm.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Child nodes are cleared using an O(n^2) loop
1 participant