[fizz][external-runtime] Fix: process mutation records before disconnecting (#26169)

> All notifications of mutations that have already been detected, but
not yet reported to the observer, are discarded. To hold on to and
handle the detected but unreported mutations, use the takeRecords()
method.
>    -- ([Mozilla docs for disconnect](

https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/disconnect))

Fizz external runtime needs to process mutation records (representing
potential Fizz instructions) before calling `disconnect()`. We currently
do not do this (and might drop some instructions).
This commit is contained in:
mofeiZ
2023-02-21 09:10:23 -08:00
committed by GitHub
parent c7967b194b
commit 70b0bbda76

View File

@@ -35,6 +35,8 @@ if (document.readyState === 'loading') {
installFizzInstrObserver(document.body);
}
handleExistingNodes();
// We can call disconnect without takeRecord here,
// since we only expect a single document.body
domBodyObserver.disconnect();
}
});
@@ -54,7 +56,7 @@ function handleExistingNodes() {
}
function installFizzInstrObserver(target /*: Node */) {
const fizzInstrObserver = new MutationObserver(mutations => {
const handleMutations = (mutations /*: Array<MutationRecord> */) => {
for (let i = 0; i < mutations.length; i++) {
const addedNodes = mutations[i].addedNodes;
for (let j = 0; j < addedNodes.length; j++) {
@@ -63,13 +65,16 @@ function installFizzInstrObserver(target /*: Node */) {
}
}
}
});
};
const fizzInstrObserver = new MutationObserver(handleMutations);
// We assume that instruction data nodes are eventually appended to the
// body, even if Fizz is streaming to a shell / subtree.
fizzInstrObserver.observe(target, {
childList: true,
});
window.addEventListener('DOMContentLoaded', () => {
handleMutations(fizzInstrObserver.takeRecords());
fizzInstrObserver.disconnect();
});
}