[whatwg/dom] MutationObserver node complete identifier (Issue #1116)

MutationObservers return added nodes when an opening tag is encountered.  For many use cases, this is not a problem as the insertions are of completed nodes, and even incomplete nodes (while streaming HTML) are generally handled gracefully.

However, for many use cases it would be useful to know when a node has closed/completed.

This pertains largely to streaming HTTP responses through a detached document that contains inline scripts.  See the relevant Google Chrome Developers HTTP 203 episode and especially [this moment](https://youtu.be/LLRig4s1_yA?t=1283) for some background. There seems to be growing interest in this approach, e.g. [this](https://blog.dwac.dev/posts/streamable-html-fragments/).

Our use case involves streaming a full page HTML response, and extracting parts of the page that have changed to dynamically update only those parts as a hybrid between SSR and CSR.  This is similar to [TurboLinks](https://github.com/turbolinks/turbolinks) where a SSR app is turned into a CSR app without requiring structural changes.  TurboLinks replaces the entire body once the response fully returns, while we'll be using MutationObservers to insert subtrees of the response as they arrive to increase responsiveness and decrease perceived load time.

# Situation 1 - Streaming scripts
One challenge of this streaming approach is that inline scripts are sandboxed.  In order to execute them, they must be extracted and re-inserted into the DOM with a new script tag and the script text copied.

Ideally these inline scripts will be executed at the moment they are inserted, as they may be operating on just-rendered content and delays could cause flashes of unstyled or unprocessed content.  An example is a script to scroll a carousel to the appropriate position the user expects.

One approach to solve this is using a MutationObserver to watch for scripts and re-execute them when found.  The problem is that if a script falls on a streaming chunk boundary, the script will be incomplete and will fail with a parsing error when executed.

See [this jsfiddle](https://jsfiddle.net/Lmkfgu71/2/) for reproduction.  "processScriptBroken()" is enabled which shows the naive implementation, which receives MutationObserver events at tag open which may represent incomplete nodes.  Observe that standard nodes can be partially streamed without issue.  Script tags only execute if they are complete within a chunk, and executing them when the MutationObserver returns them causes syntax errors in the console.

See [this jsfiddle](https://jsfiddle.net/64cgrmz5/1/) which implements a workaround by only executing pending scripts once the following node is received or the input ends.  This ensures all scripts execute only once closed.  This could be further tightened by executing a script immediately if the current set of mutations has additional addedNodes.

This situation would be simplified if MutationObserver provided a callback when each script tag completes.

# Situation 2 - onComplete node splicing + Animations
Another use case that applies to streaming HTML content + MutationObservers is knowing when a subtree is complete to execute insertion or animations.

In the first case, we want to pull subcomponents out of the response to replace their existing counterparts only once they are complete to avoid rendering partial subtrees.  We want to do this exactly when each node completes to make the updates render faster to the user. We could use a similar technique to the scripts above, but the logic gets even more complicated as we have to wait not just for the next node, but the next node after our current subtree which could be hundreds of nodes away.  An on-complete callback would solve this elegantly.

Similarly, animations run on streaming content could break or appear janky if they are run when their tag opens but content is incomplete. 
 Ideally we will start certain animations as soon as a component is fully rendered.  This would apply even to a traditionally rendered page, not just streaming through a detached document.

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/1116
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/dom/issues/1116@github.com>

Received on Friday, 7 October 2022 23:55:38 UTC