append('text'), splitText() and range edits can leave a string split across adjacent text nodes, some empty. The page looks the same, but firstChild.data and childNodes.length mislead. normalize() merges adjacent text nodes and deletes empty ones throughout a subtree; whitespace-only nodes between elements stay, because they are not empty.
<p id="p" hidden>A</p><pre id="out" style="margin:0"></pre>
<script>
const p = document.querySelector('#p');
p.append('B', '', 'C'); // three more text nodes, one empty
const before = p.childNodes.length;
p.normalize();
document.querySelector('#out').textContent =
`before: ${before} nodes, after: ${p.childNodes.length} node "${p.firstChild.data}"`;
</script>