Skip to content

self defined progressive hydration for custom elements #3

@thescientist13

Description

@thescientist13

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.

Metadata

Metadata

Labels

Type

No type

Projects

Status

📋 Backlog

Relationships

None yet

Development

No branches or pull requests

Issue actions