Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Blazor] Using MutationObserver for detection of DOM element removal - should observe document.body #33842

Closed
hakenr opened this issue Oct 11, 2024 · 10 comments · Fixed by #34379

Comments

@hakenr
Copy link
Member

hakenr commented Oct 11, 2024

Description

A suggested approach for handling DOM cleanup tasks during component disposal is to use MutationObserver to detect element removal from the DOM and trigger the cleanup.

The sample code currently attaches the MutationObserver to target.parentNode, which works until parentNode itself is removed from the DOM. This is a common scenario, for example, when navigating to a new page, which causes the entire page component to be removed from the DOM. In such cases, any child components observing changes within the page won't be cleaned up properly.

My proposal is to modify the sample to observe document.body with the MutationObserver, as this should be a more reliable target that won’t lose mutations as easily.

However, since I’m not an expert on mutation observers, I’d appreciate feedback from the original sample author/reviewer (@MackinnonBuck?). There might be specific issues or performance considerations to keep in mind. For instance, as a performance optimization, we might want to use a single, shared MutationObserver that maintains a list of elements to track for removal, rather than creating a separate observer for every individual element.

Page URL

https://learn.microsoft.com/en-us/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-8.0

Content source URL

https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/blazor/javascript-interoperability/index.md

Document ID

49fa31d8-72a6-01a1-027d-6edeac9e0fc4

Article author

@guardrex

Related Issues

Copy link
Contributor

🍂🎃🏮 Autumn Skies and Pumpkin Pies! 🥧☕🍂

Stand by! A green dinosaur 🦖 will arrive shortly to assist.

@hakenr
Copy link
Member Author

hakenr commented Oct 11, 2024

@guardrex Hope everything's okay for you; looks like Hurricane Milton is causing some serious issues.

I'll put together a PR if we can agree on the best approach.

@guardrex
Copy link
Collaborator

Thanks ... I survived it! The tornadoes 🌪 were the worst part here. I just hope my fellow Americans wake up to climate change before things get vastly worse down the road.

On the issue, yes ... let's get @MackinnonBuck's input.

@guardrex
Copy link
Collaborator

UPDATE (10/29): Still no response due to high priority work for the .NET 9 release. I'll keep after them on this 😄.

@guardrex
Copy link
Collaborator

UPDATE (11/22): @MackinnonBuck is still unavailable. He'll be here as soon as he's free (and back, as I think he's OOF 🏖 at the moment) to take a look.

@guardrex
Copy link
Collaborator

guardrex commented Dec 5, 2024

UPDATE (12/5): Still unavailable, and we're working down a backlog of other issues right now. This will need to wait a bit longer. Sorry for the delay, @hakenr. Making matters a little worse, there are some internal MS things going on in the background that are slowing things down right now ... and pile on the usual slow holiday season ⛄ ... vacations and exhausted workers 😩. We'll get to this as soon as possible.

@SteveSandersonMS
Copy link
Member

Yes, this appears to be correct: whatwg/dom#533

However, observing document.body has perf implications since it means your observer is running callback logic for literally all DOM updates, whether or not they have anything to do with your element.

I would suggest the preferred approaches are:

  • In cases where you can identify a suitable ancestor node to observe, use MutationObserver. Ideally this ancestor would be something fairly scoped to the changes you want to observe, rather than document.body
  • Otherwise, instead of using MutationObserver consider using a custom element and disconnectedCallback. This will always fire when your custom element is disconnected, no matter where it was in the DOM relative to the DOM change.

However it's not our job to document web programming in general, so if we can stay away from giving too much detail on this that would be helpful. We could just suggest the two approaches as options without providing detailed sample code, for example.

@guardrex
Copy link
Collaborator

Thanks @SteveSandersonMS ... @hakenr, do you want to compose that for the article on a PR, or do you prefer I place a PR with your review to iron out any rough spots?

@hakenr
Copy link
Member Author

hakenr commented Dec 12, 2024

@guardrex
Not sure about the content of the PR.
We could probably explain the caveats of the MutationObserver and suggest the approaches Steve proposed.
I’m still not sure the current sample with MutationObserver is worth keeping in the docs, as its usability is extremely limited.
I’d prefer it if you created the PR.

@guardrex
Copy link
Collaborator

guardrex commented Dec 12, 2024

Ok, I'll do it. I'll see if I can synthesize your remarks and Steve's remarks into a few paragraphs at the end of the section. I'll see if I can take care of it tomorrow morning.

UPDATE (12/14): Obviously, I was delayed. I'll see if I can get things going with this early next week. 🏃‍♂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants