@samitouri / QOS-React-2 / commits / 70b0bbda76

[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).

mofeiZ committed Feb 21, 2023 at 09:10 UTC 70b0bbda767ed016925889e8952b10f49921c0cf
1 file changed +7 -2
packages/react-dom-bindings/src/server/ReactDOMServerExternalRuntime.js
+7 -2
@@ -35,6 +35,8 @@ if (document.readyState === 'loading') {
35 installFizzInstrObserver(document.body);
36 }
37 handleExistingNodes();
38 + // We can call disconnect without takeRecord here,
39 + // since we only expect a single document.body
40 domBodyObserver.disconnect();
41 }
42 });
@@ -54,7 +56,7 @@ function handleExistingNodes() {
56 }
57
58 function installFizzInstrObserver(target /*: Node */) {
57 - const fizzInstrObserver = new MutationObserver(mutations => {
59 + const handleMutations = (mutations /*: Array<MutationRecord> */) => {
60 for (let i = 0; i < mutations.length; i++) {
61 const addedNodes = mutations[i].addedNodes;
62 for (let j = 0; j < addedNodes.length; j++) {
@@ -63,13 +65,16 @@ function installFizzInstrObserver(target /*: Node */) {
65 }
66 }
67 }
66 - });
68 + };
69 +
70 + const fizzInstrObserver = new MutationObserver(handleMutations);
71 // We assume that instruction data nodes are eventually appended to the
72 // body, even if Fizz is streaming to a shell / subtree.
73 fizzInstrObserver.observe(target, {
74 childList: true,
75 });
76 window.addEventListener('DOMContentLoaded', () => {
77 + handleMutations(fizzInstrObserver.takeRecords());
78 fizzInstrObserver.disconnect();
79 });
80 }