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

Better handle component definitions that should be deferred #10

Open
JRJurman opened this issue Sep 29, 2024 · 0 comments
Open

Better handle component definitions that should be deferred #10

JRJurman opened this issue Sep 29, 2024 · 0 comments

Comments

@JRJurman
Copy link
Member

Summary

Most component definitions / libraries today defer registering component definitions because they allow for better progressive enhancement - that is to say, load your base HTML content first, then run JS to enhance would-be Custom Elements.

This can cause what is known as "Flash of undefined components" (or FOUC), but can be desirable when streamed content would fail to process as expected. For example, let's say you had the following template:

<alerty-button>
  <button>Hello World</button>
</alerty-button>

If we define <alerty-button> before this block, then in connectedCallback, the slot and text content will be empty. It will effectively look like:

<alerty-button>
  #shadow-dom
</alerty-button>

If we define <alerty-button> after this block, then we will have all the expected elements by the time connectedCallback triggers:

<alerty-button>
  #shadow-dom
  <button>Hello World</button>
</alerty-button>

This can make building component definitions (especially small examples) much more straight forward, rather than having to add listeners or mutation observers for new content (especially if we might never expect this content to change).

Why this is relevant and specific to Tram-Deco? Well, since Tram-Deco encourages in-template component definitions and the TramDeco.processTemplate() function, there isn't an elegant obvious way to "defer processing until after the template completes". This can make mundane or simple examples more challenging to build (see the README example today, which requires adding a slotchange event).

Additionally, this means that users who might want to defer all script loading to AFTER template parsing can't defer Tram-Deco, because there's no obvious way to both call the processTemplate function in a script that can be deferred - see example here.

Ideally we'd be able to defer the processing of templates, and allow people to defer importing Tram-Deco. There are a few ways to do this today:

  1. Wrap TramDeco.processTemplate() in a DOMContentLoaded event (example)
  2. Use type="module" in the script tag (example)

None of these options are very elegant though:

  1. The code required here feels antiquated, and feels like a lot to copy-and-paste every time
  2. type="module" feels disingenuous, since we're not doing this for the purpose of loading any modules

Potential Solution

Tentatively, I think the best solution may be to add some kind of defer option to processTemplate, that allows us to queue the component definition after DOMContentLoaded. This would be a small amount of bloat, that allows developers to easily choose when they want their component definitions to be registered. Adding an options parameter might not be a terrible idea either if we eventually want to support scoped custom element registries.

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

1 participant