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

self defined progressive hydration for custom elements #3

Open
5 tasks
thescientist13 opened this issue Apr 25, 2022 · 2 comments · May be fixed by #2
Open
5 tasks

self defined progressive hydration for custom elements #3

thescientist13 opened this issue Apr 25, 2022 · 2 comments · May be fixed by #2
Assignees
Labels
documentation Improvements or additions to documentation expirement help wanted Extra attention is needed
Milestone

Comments

@thescientist13
Copy link
Member

thescientist13 commented Apr 25, 2022

Overview

Coming out of conversation around hydration within the WCCG, was thinking about what might be possible if we could intercept the customElements.define call at the browser level? Maybe we could use it to let a WebComponent bootstrap itself with its own intersection observer logic, so instead of having to defining everything via attributes and / or some framework glue layer, e.g

<my-element custom:dsl="x,y,z"></my-element>

A custom element could do this itself via a contract / community protocol, like using a static method or member, which could initialize its own Intersection Observer maybe?

class Counter extends HTMLElement {
  static __secret() {
    console.debug('sssshhh!  this is a secret :)')
    // do stuff with onload function, IntersectionObserver, Mutation Observer
  }
}

export { Counter }

customElements.define('wcc-counter', Counter)

However, this presumably introduces a chicken and the egg scenario though because at this point a CE is calling customElements.define, the JS would already have been loaded on to the point, which kind of defeats the purpose somewhat.

So there will still need to be a way to decouple the "intersection" trigger from the component itself, which I suppose does benefit a compiler based tool, so there is that. 😄

Details

My thought there is that for the above example, we could extract the static method from the class and just providing that to be include that at runtime.

async ExpressionStatement(node) {
  const { expression } = node;

  if(/* is custom element */) {
    const tagName = node.expression.arguments[0].value;
    const instanceName = node.expression.arguments[1].name;
    const module = (await import(moduleURL))[instanceName];
    const hydrate = module.hydrate || undefine;

    deps[tagName] = {
      instanceName
      moduleURL,
      hydrate
    }
  }
}

And then we inject just that function into the runtime. So in theory, there is no wcc overhead, it is purely user based.

What is neat about this I think, is that you can now open up levels and degrees of hydration aside from just top down which would be a limitation of having to express the attributes everywhere up front. So depending on how many

Additional thoughts / goals

  1. Make a good demo / use case
  2. See if we could take inspiration from from lazyDefine proposal
  3. Explore to see if Proxy's could be useful here
  4. Think about scaling as more CEs are added to the runtime via hydrate since this would push all that JavaScript to the runtime (a la Svelte). Which probably won't be much in the grand scheme of things, be entirely coming from userland, and entirely opt-in.
  5. Bonus points for stripping hydrate out of the custom elements class definition as well to avoid shipping the bytes at runtime

Opened an issue in the WCCG's Community Protocols repo.

@thescientist13 thescientist13 added the feature New feature or request label Apr 25, 2022
@thescientist13 thescientist13 self-assigned this Apr 25, 2022
@thescientist13 thescientist13 linked a pull request Apr 25, 2022 that will close this issue
3 tasks
@thescientist13 thescientist13 added this to the 1.0 milestone Apr 25, 2022
@thescientist13 thescientist13 linked a pull request Apr 25, 2022 that will close this issue
3 tasks
@thescientist13
Copy link
Member Author

thescientist13 commented Apr 26, 2022

I wonder if MutationObserver can also be useful for fine grained loading? Or could maybe be useful for #5 , though I don't think MutationObserver exists in NodeJS? 🤔

@thescientist13
Copy link
Member Author

@thescientist13 thescientist13 added the help wanted Extra attention is needed label Apr 30, 2022
@thescientist13 thescientist13 changed the title self hydrating custom elements progressive self hydrating custom elements May 1, 2022
@thescientist13 thescientist13 added the documentation Improvements or additions to documentation label May 1, 2022
@thescientist13 thescientist13 changed the title progressive self hydrating custom elements self defined progressive hydration for custom elements May 19, 2022
@thescientist13 thescientist13 pinned this issue May 20, 2022
@thescientist13 thescientist13 added expirement and removed feature New feature or request labels May 27, 2022
@thescientist13 thescientist13 unpinned this issue Aug 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation expirement help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant