[whatwg/dom] `MutationObserver` `childList` events fire in unexpected and grouped order, requiring complex workarounds. (Issue #1111)

> **Note** Re-opening of #1105 because that issue was closed for not being succinct, although the problem was described fine. This time I will not include additional comments showing attempts to *work around* the problem.
> 
> I'm not asking for usage help.
> 
> I'm pointing out the difficulties involved with writing proper `MutationObserver` for child tracking (across a tree, not just on a single element), and the intent of this issue is to spark ideas for a better API (again, not usage help).

---

Trying to port from DOM Mutation Events, or from dis/connectedCallbacks on children (which aren't available on builtin elements) to a `MutationObserver` pattern that initializes or cleans up code based on when children are connected then disconnected (which works with built-in and custom elements), is nearly impossible without an immense and cumbersome effort.

I've been using `MutationObserver` for years now, and am now discovering bugs in certain cases that I didn't notice before (I should have written better tests, but also `MutationObserver` is complicated and cumbersome, the latter being my point and wishing to ideate a better API).

# The Problem

> **Note** I will only describe the problem here. #1105 has examples of complicated user code that attempt to *work around the problem*, but I'm not asking for help with those example. I'm merely trying to show the complexity of the problem, and wishing for a better API.

> **Note** Also note `MutationObserver` is not bad for all its use cases, the problem I will describe here only relates to tracking children. In the ideal future world, a new API would replace the `childList` feature only, and that is the only scope of this issue.

In the following example, the connected and disconnected events fire in the wrong order, which leave connected children erroneously cleaned up:

https://codepen.io/trusktr/pen/oNqrNXE/3aad3bb7315877d00c7c42e3d77fed5a?editors=1010

In this one, the behavior is a bit different, but still not as desired:

https://codepen.io/trusktr/pen/MWVMWKe/091e6f303bd773f2754304fb1c9bff30?editors=1000

With standard `connectedCallback` and `disconnectedCallback`, they always fire in this order per each custom element when an element disconnected and re-connected:

```
disconnectedCallback()
connectedCallback()
```

However, with this naive `MutationObserver` usage, the order (in the above two examples) when a child is removed then re-connected is

```
child connected
child removed
```

which will cause unexpected behavior, and will require people to start trying to work around the issue as I've described in further comments in #1105.

---

DOM Mutation Events are much much easier to use. `MutationObserver` is incredibly difficult to work with. (wrt observing children)

# Possible Solutions:

1. `MutationObserver` event callbacks could be called in such a way that `childList` records are perfectly interleaved in the same order as actions that happened in the DOM. This would complete solve the problem, and code would remain simple.
2. All the issues of Mutation Events could be fixed and exposed in a new event API.
  - There is not any aspect of event patterns in general that make them inherently bad. It just happens to be that the way Mutation Events worked was not ideal **and** browsers implemented them differently with bugs. That's not to say we can't come up with an event pattern that works well.
4. A new synchronous alternative to Mutation Events could be created that would be no worse than today's `connectedCallback` and `disconnectedCallback` methods (those are synchronous, and synchronicity is not the issue, but code ordering is), being an opt-in feature with no such thing as event bubbling in the way or the heaviness of `EventTarget` (`Event` being designed specifically for a tree of nodes, when not all event patterns need to be associated with a tree at all).

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

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

Received on Sunday, 11 September 2022 18:19:35 UTC