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

Import order affects connectedCallback order #103

Closed
valdrinkoshi opened this issue Sep 26, 2016 · 3 comments
Closed

Import order affects connectedCallback order #103

valdrinkoshi opened this issue Sep 26, 2016 · 3 comments

Comments

@valdrinkoshi
Copy link
Contributor

We have 2 custom elements defined in the respective files:

// x-parent.html
  window.customElements.define('x-parent', class extends HTMLElement {
    connectedCallback() {
      console.log(this.localName, 'connected');
    }
  });

// x-child.html
  window.customElements.define('x-child', class extends HTMLElement {
    connectedCallback() {
      console.log(this.localName, 'connected');
    }
  });

They get imported and used in the main document:

<link rel="import" href="x-child.html">
<link rel="import" href="x-parent.html">

<x-parent>
  <x-child></x-child>
</x-parent>

In native CustomElements v1, the order of imports affects the order of connectedCallback calls, meaning that if x-child is imported before x-parent (like in the above example), its connectedCallback will be invoked before the x-parent one

x-child connected
x-parent connected

This does not happen with the v1 polyfill, which will output

x-parent connected
x-child connected
@valdrinkoshi
Copy link
Contributor Author

@sorvell @cdata @blasten FYI

@notwaldorf
Copy link
Contributor

notwaldorf commented Sep 27, 2016

@sorvell @kevinpschaaf fwiw i think this is exactly what i was seeing today

@kevinpschaaf
Copy link
Collaborator

There are a few things here to note:

  • The native behavior did in fact change between V0 & V1
    • In V0 upgrades generally went in parse order (as long as import tags were parsed before the custom elements they registered)
    • In V1 upgrades generally will now go in registration order as opposed to parse order
  • The V1 polyfill does not currently upgrade in registration order as per the spec; you will generally see them upgraded in parse order
    • Making the V1 polyfill match native V1 ordering is difficult: it either require a naive entire-import-tree-walk for every customElements.define call which would likely be performance-non-viable, or else implementing a "candidate map/list" of previously discovered custom element candidates which would seem to introduce quite a bit of complexity and coupling between the Custom Elements and HTMLImports polyfill
    • cc @justinfagnani on this point
  • All that said, element code really needs to be hardened against different import ordering anyway
    • That is, an element that expects/assumes it will be registered before an element that may be provided as a light-DOM descendant will break in a lot of scenarios where that ordering isn't possible (e.g. lazy patterns, other earlier app dependencies requiring the light dom child to be registered, etc.)
    • While annoying, this fact somewhat erodes the cost/benefit of actually doing the work to make the polyfills match the spec
  • Specifically for use cases involving descendants firing events to register with an ancestor, where the ancestor needs to have listened for the event first:
    • One gambit worked out is:
      1. Ancestor registers for the event in constructor or connectedCallback
      2. Descendant fires event in requestAnimationFrame enequeued from constructor or connectedCallback
      3. Ancestor can perform work on the complete list of descendants in requestAnimationFrame + one microtask
    • The above should probably be bundled into a Polymer helper method or behavior, and made robust against the browser yielding prior to fully parsing the document by making requestAnimationFrame above actually poll document.readyState ane enqueue more requestAnimationFrame's until the document becomes 'interactive'

@dfreedm dfreedm transferred this issue from webcomponents/custom-elements Jun 7, 2019
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

No branches or pull requests

3 participants