-
Notifications
You must be signed in to change notification settings - Fork 383
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
Some sort of guarantee on custom element lifecycle order of events #737
Comments
This is by design. So you design robust components that can be created imperatively. |
You said that
Given that constructors can only be used in a custom element registry once (effectively making the registry a Bi-Map), would it work for your use cases to have a method like Then you could just use it like this: class ElementOne extends HTMLElement {
async connectedCallback() {
await customElements.whenRegistered(ElementTwo)
}
} |
I don't see a lot of actionable work here; as noted by @annevk this is working as designed. Shall we close? |
This is mostly a problem when creating them declaratively: they start in HTML, then parsed, and depending on various factors, children (of an element with child-observing logic) may or may not be upgraded inside of (for example) the observing-element's When I create elements imperatively, this problem doesn't exist in my cases.
That would be helpful, then we don't need to care what the elements are named! Something like if (!customElements.get(SomeElementConstructor))
await customElements.whenDefined(SomeElementConstructor) |
That is already tracked by #566. I'm closing this since not being able to depend on your children being ready is by design. You'll need to use mutation observers. |
It'd be nice to have some sort of guarantee on the order in which certain methods like
connectedCallback
are fired during parsing of HTML, and in other cases.The problem
In #559, I have some problems, which ultimately stem from the fact that the order in which elements are upgraded in the DOM (breadth-first vs depth-first) depends on whether upgrade happens
customElements.define()
in a<script>
tag in the<head>
, before the<body>
is parsed)<script>
tag at the end of the<body>
so that by the timecustomElements.define()
is called, the DOM already exists)Either of the cases apply at other points in runtime too:
customElements.define()
is used to define an element then after that the respective type of element is created and appended into DOM.customElements.define()
Here is a demonstration of one form of each case (though other forms exist):
https://jsfiddle.net/wkwmzLwL
The order of upgrade is reversed between those two cases.
Why is this bad?
This leads to ugly conditional checking and/or deferral hacks needed in order for parent elements to be able to always work with child elements where the child elements are expected to be certain types of custom elements. This can lead to harder-to-maintain code and increases surface area for unexpected and weird bugs.
Here's an example of a hack that solves the problem from the previous fiddle:
https://jsfiddle.net/aqp4uaja
Solution?
I'm not quite sure what a solution (for browsers to implement) would be exactly. Some solution ideas:
childConnectedCallback
s are only called after child elements are upgraded iff the child elements have already been defined bycustomElements.define
.customElements
, then it doesn't make sense to wait for upgrades that may never happen. In this case, I'm not sure what's a clear solution.DOMException: An element named 'some-thing' has already been created. Elements should be defined before they are created.
HTMLUnknownElement
s to upgrade, which can cost more CPU.connectedCallback
, which makes it possible to ensure that child elementconnectedCallbacks
are called first, in depth-first order.Basically, some consistency would be great: it would lend to cleaner and more solid Web Components with less hacks and less surface area for bugs.
The text was updated successfully, but these errors were encountered: