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

fix(synthetic-shadow): use native mutation observer for portal elements #1596

Merged
merged 5 commits into from
Nov 8, 2019

Conversation

jodarove
Copy link
Contributor

elements marked as lwc:dom=manual.

It also adds a performance optimization by not listening to the whole subtree.

Does this PR introduce breaking changes?

  • No, it does not introduce breaking changes.

@@ -25,15 +30,21 @@ let portalObserver: MutationObserver | undefined;

const portalObserverConfig: MutationObserverInit = {
childList: true,
subtree: true,
subtree: false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is false by default, just remove it.

return; // nothing to do here, it is already correctly patched
}
setShadowRootResolver(node, fn);
if (node instanceof Element) {
// Root LWC elements can't contain slots, therefore we stop listening mutations.
Copy link
Contributor

@caridy caridy Oct 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comment is wrong... "Root LWC elements can't get content slotted into them, therefore we don't observe their children."

if (isUndefined(previousNodeShadowResolver)) {
// we only care about Element without shadowResolver (no MO.observe has been called)
MutationObserverObserve.call(portalObserver, node, portalObserverConfig);
}
setShadowToken(node, shadowToken);
Copy link
Contributor Author

@jodarove jodarove Oct 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@caridy why do we use this (other than to propagate in the portal elements)? This code path is not adding it to the host elements.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this has to be accommodated, it should be added to custom elements, but not to the children elements of a it. I think we can keep the old condition if (node instanceof Element) {, then do the setShadowtoken(), then checking if it is not host to do the rest, which is install mutation and attempt to recursively patch all children.

elements marked as lwc:dom=manual.

It also adds a performance optimization by not listening to the whole subtree.
@jodarove jodarove force-pushed the jodarove/improve-mo-for-dom-manual branch from 3efdc6a to dc98cf6 Compare October 29, 2019 02:36
Copy link
Contributor

@caridy caridy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, maybe some extra tests... but that will be tricky to proof.

if (isUndefined(previousNodeShadowResolver)) {
// we only care about Element without shadowResolver (no MO.observe has been called)
MutationObserverObserve.call(portalObserver, node, portalObserverConfig);
}
// recursively patching all children as well
const childNodes = getInternalChildNodes(node);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@caridy, @ravijayaramappa since for portals we don't observe mutations on LWC components, what do you think about using the native apis? (childNodesGetter)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that's a great idea. Since this element is not a host, the only other option is to be a slot, which we don't really care much since we are saying that slots are only good slots if they are coming from template.... we can just use childNodesGetter here to speed things up.

@salesforce-cla
Copy link

Thanks for the contribution! Before we can merge this, we need @jodarove to sign the Salesforce.com Contributor License Agreement.

ShadowRootResolver,
getShadowRootResolver,
isHostElement,
} from './shadow-root';
import { setShadowToken, getShadowToken } from './shadow-token';

const MO = MutationObserver;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid caching the MutationObserver in a local const. I had issues where const MO = MutationObserver was resolving the value from the window instead of the imported value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this.

Copy link
Contributor

@ravijayaramappa ravijayaramappa Oct 30, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had an issue where the following code would resolve MutationObserver on window in the const assignment. So it would get the polyfilled MO.

import { MutationObserver, MutationObserverObserve } from '../env/mutation-observer';
const MO = MutationObserver;

I cannot repro it anymore. So I was suggesting not to use the const just to be safe. Import the MutationObserver and directly use it instead of assigning it to a const.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, yes... the order might be wrong... better to import it from the cached env file.

@ravijayaramappa ravijayaramappa changed the title fix(synthetic-shadow): use native mutation observer for fix(synthetic-shadow): use native mutation observer for portal elements Oct 30, 2019
Copy link
Contributor

@caridy caridy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but we should way for @ravijayaramappa to review this in details.

@jodarove jodarove merged commit 4b5995f into master Nov 8, 2019
@jodarove jodarove deleted the jodarove/improve-mo-for-dom-manual branch November 8, 2019 22:52
ravijayaramappa pushed a commit that referenced this pull request Nov 27, 2019
…ts (#1596)

* fix(synthetic-shadow): use native mutation observer for elements marked as lwc:dom=manual.
It also adds a performance optimization by not listening to the whole subtree.
ravijayaramappa added a commit that referenced this pull request Nov 27, 2019
…ts (#1627)

* fix(synthetic-shadow): use native mutation observer for portal elements (#1596)

* fix(synthetic-shadow): use native mutation observer for elements marked as lwc:dom=manual.
It also adds a performance optimization by not listening to the whole subtree.

* fix: include mo polyfill
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants