Skip to content

[labs/ssr] Add basic event support#2309

Closed
justinfagnani wants to merge 1 commit intomainfrom
ssr-events
Closed

[labs/ssr] Add basic event support#2309
justinfagnani wants to merge 1 commit intomainfrom
ssr-events

Conversation

@justinfagnani
Copy link
Collaborator

This is a start of what it would look like to add event support to SSR. It uses Node's Event and EventTarget classes and extends EventTarget to have a parent that it can dispatch to to implement bubbling. stopPropagation(), etc., should work, but aren't tested yet.

The big open questions are:

  • Can we have an event path of just the custom elements without materializing the built-ins that would be on the path with a full DOM structure? This seems ok if the only event patterns we support are for cross-custom-element communication, ie context.
  • Where do elements install event listeners? I added a call to connectedCallback() in here, but that only doesn't throw because none of the test elements do anything with the DOM in connectedCallback(). That wouldn't be viable in general.
  • Do we need to implement the capture phase?
  • How could we implement the proper composed path? We would need some concept of slotted elements being in the custom element instance stack.

@changeset-bot
Copy link

changeset-bot bot commented Nov 21, 2021

⚠️ No Changeset found

Latest commit: 0af8eda

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@google-cla google-cla bot added the cla: yes label Nov 21, 2021
@github-actions
Copy link
Contributor

github-actions bot commented Nov 21, 2021

📊 Tachometer Benchmark Results

Summary

nop-update

  • lit-html-kitchen-sink: unsure 🔍 -3% - +7% (-1.01ms - +2.36ms)
    this-change vs tip-of-tree

render

  • lit-element-list: unsure 🔍 -2% - +4% (-1.93ms - +3.64ms)
    this-change vs tip-of-tree
  • lit-html-kitchen-sink: unsure 🔍 -0% - +5% (-0.03ms - +1.91ms)
    this-change vs tip-of-tree
  • lit-html-repeat: unsure 🔍 -7% - +0% (-1.05ms - +0.05ms)
    this-change vs tip-of-tree
  • lit-html-template-heavy: unsure 🔍 -3% - +3% (-2.29ms - +1.86ms)
    this-change vs tip-of-tree
  • reactive-element-list: unsure 🔍 -2% - +2% (-1.55ms - +1.60ms)
    this-change vs tip-of-tree

update

  • lit-element-list: unsure 🔍 -2% - +1% (-17.29ms - +11.24ms)
    this-change vs tip-of-tree
  • lit-html-kitchen-sink: unsure 🔍 -4% - +6% (-3.97ms - +6.91ms)
    this-change vs tip-of-tree
  • lit-html-repeat: unsure 🔍 -2% - +2% (-7.27ms - +6.51ms)
    this-change vs tip-of-tree
  • lit-html-template-heavy: unsure 🔍 -5% - +0% (-7.12ms - +0.06ms)
    this-change vs tip-of-tree
  • reactive-element-list: unsure 🔍 -1% - +3% (-6.60ms - +23.49ms)
    this-change vs tip-of-tree

update-reflect

  • lit-element-list: unsure 🔍 -1% - +2% (-13.52ms - +15.55ms)
    this-change vs tip-of-tree
  • reactive-element-list: unsure 🔍 -1% - +2% (-11.82ms - +19.31ms)
    this-change vs tip-of-tree

Results

lit-element-list

render

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
99.47ms - 102.86ms-unsure 🔍
-2% - +4%
-1.93ms - +3.64ms
faster ✔
20% - 24%
25.62ms - 31.38ms
tip-of-tree
tip-of-tree
98.10ms - 102.52msunsure 🔍
-4% - +2%
-3.64ms - +1.93ms
-faster ✔
20% - 25%
26.15ms - 32.57ms
previous-release
previous-release
127.34ms - 132.00msslower ❌
25% - 31%
25.62ms - 31.38ms
slower ❌
26% - 33%
26.15ms - 32.57ms
-

update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
842.01ms - 862.43ms-unsure 🔍
-2% - +1%
-17.29ms - +11.24ms
faster ✔
7% - 10%
62.59ms - 91.45ms
tip-of-tree
tip-of-tree
845.29ms - 865.21msunsure 🔍
-1% - +2%
-11.24ms - +17.29ms
-faster ✔
6% - 9%
59.74ms - 88.25ms
previous-release
previous-release
919.05ms - 939.44msslower ❌
7% - 11%
62.59ms - 91.45ms
slower ❌
7% - 10%
59.74ms - 88.25ms
-

update-reflect

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
917.49ms - 935.39ms-unsure 🔍
-1% - +2%
-13.52ms - +15.55ms
faster ✔
4% - 6%
34.06ms - 63.71ms
tip-of-tree
tip-of-tree
913.98ms - 936.88msunsure 🔍
-2% - +1%
-15.55ms - +13.52ms
-faster ✔
3% - 7%
33.45ms - 66.36ms
previous-release
previous-release
963.51ms - 987.15msslower ❌
4% - 7%
34.06ms - 63.71ms
slower ❌
4% - 7%
33.45ms - 66.36ms
-
lit-html-kitchen-sink

render

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
40.70ms - 42.27ms-unsure 🔍
-0% - +5%
-0.03ms - +1.91ms
faster ✔
18% - 23%
8.91ms - 12.15ms
tip-of-tree
tip-of-tree
39.98ms - 41.11msunsure 🔍
-5% - +0%
-1.91ms - +0.03ms
-faster ✔
20% - 24%
9.94ms - 12.99ms
previous-release
previous-release
50.60ms - 53.43msslower ❌
21% - 30%
8.91ms - 12.15ms
slower ❌
24% - 32%
9.94ms - 12.99ms
-

update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
108.66ms - 117.71ms-unsure 🔍
-4% - +6%
-3.97ms - +6.91ms
unsure 🔍
-7% - +3%
-8.37ms - +3.08ms
tip-of-tree
tip-of-tree
108.69ms - 114.74msunsure 🔍
-6% - +3%
-6.91ms - +3.97ms
-unsure 🔍
-7% - +0%
-8.75ms - +0.52ms
previous-release
previous-release
112.31ms - 119.34msunsure 🔍
-3% - +7%
-3.08ms - +8.37ms
unsure 🔍
-1% - +8%
-0.52ms - +8.75ms
-

nop-update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
32.97ms - 35.74ms-unsure 🔍
-3% - +7%
-1.01ms - +2.36ms
unsure 🔍
-5% - +4%
-1.82ms - +1.45ms
tip-of-tree
tip-of-tree
32.71ms - 34.64msunsure 🔍
-7% - +3%
-2.36ms - +1.01ms
-unsure 🔍
-6% - +1%
-2.17ms - +0.45ms
previous-release
previous-release
33.66ms - 35.42msunsure 🔍
-4% - +5%
-1.45ms - +1.82ms
unsure 🔍
-1% - +6%
-0.45ms - +2.17ms
-
lit-html-repeat

render

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
13.00ms - 13.68ms-unsure 🔍
-7% - +0%
-1.05ms - +0.05ms
faster ✔
2% - 8%
0.23ms - 1.10ms
tip-of-tree
tip-of-tree
13.40ms - 14.27msunsure 🔍
-0% - +8%
-0.05ms - +1.05ms
-unsure 🔍
-5% - +2%
-0.68ms - +0.35ms
previous-release
previous-release
13.73ms - 14.28msslower ❌
2% - 8%
0.23ms - 1.10ms
unsure 🔍
-3% - +5%
-0.35ms - +0.68ms
-

update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
348.94ms - 357.66ms-unsure 🔍
-2% - +2%
-7.27ms - +6.51ms
faster ✔
29% - 32%
146.58ms - 164.46ms
tip-of-tree
tip-of-tree
348.34ms - 359.02msunsure 🔍
-2% - +2%
-6.51ms - +7.27ms
-faster ✔
29% - 32%
145.68ms - 164.60ms
previous-release
previous-release
501.01ms - 516.63msslower ❌
41% - 47%
146.58ms - 164.46ms
slower ❌
41% - 47%
145.68ms - 164.60ms
-
lit-html-template-heavy

render

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
66.10ms - 68.50ms-unsure 🔍
-3% - +3%
-2.29ms - +1.86ms
faster ✔
15% - 19%
11.95ms - 15.62ms
tip-of-tree
tip-of-tree
65.82ms - 69.21msunsure 🔍
-3% - +3%
-1.86ms - +2.29ms
-faster ✔
14% - 19%
11.37ms - 15.76ms
previous-release
previous-release
79.69ms - 82.48msslower ❌
18% - 23%
11.95ms - 15.62ms
slower ❌
16% - 24%
11.37ms - 15.76ms
-

update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
132.34ms - 136.67ms-unsure 🔍
-5% - +0%
-7.12ms - +0.06ms
faster ✔
12% - 17%
18.73ms - 26.30ms
tip-of-tree
tip-of-tree
135.17ms - 140.90msunsure 🔍
-0% - +5%
-0.06ms - +7.12ms
-faster ✔
10% - 15%
14.76ms - 23.20ms
previous-release
previous-release
153.91ms - 160.12msslower ❌
14% - 20%
18.73ms - 26.30ms
slower ❌
10% - 17%
14.76ms - 23.20ms
-
reactive-element-list

render

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
69.67ms - 71.76ms-unsure 🔍
-2% - +2%
-1.55ms - +1.60ms
unsure 🔍
-2% - +2%
-1.54ms - +1.33ms
tip-of-tree
tip-of-tree
69.51ms - 71.86msunsure 🔍
-2% - +2%
-1.60ms - +1.55ms
-unsure 🔍
-2% - +2%
-1.66ms - +1.39ms
previous-release
previous-release
69.85ms - 71.80msunsure 🔍
-2% - +2%
-1.33ms - +1.54ms
unsure 🔍
-2% - +2%
-1.39ms - +1.66ms
-

update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
844.07ms - 868.77ms-unsure 🔍
-1% - +3%
-6.60ms - +23.49ms
unsure 🔍
-2% - +2%
-17.77ms - +17.40ms
tip-of-tree
tip-of-tree
839.38ms - 856.58msunsure 🔍
-3% - +1%
-23.49ms - +6.60ms
-unsure 🔍
-3% - +1%
-23.81ms - +6.56ms
previous-release
previous-release
844.09ms - 869.13msunsure 🔍
-2% - +2%
-17.40ms - +17.77ms
unsure 🔍
-1% - +3%
-6.56ms - +23.81ms
-

update-reflect

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
952.52ms - 976.47ms-unsure 🔍
-1% - +2%
-11.82ms - +19.31ms
unsure 🔍
-1% - +3%
-5.61ms - +26.48ms
tip-of-tree
tip-of-tree
950.81ms - 970.69msunsure 🔍
-2% - +1%
-19.31ms - +11.82ms
-unsure 🔍
-1% - +2%
-7.90ms - +21.29ms
previous-release
previous-release
943.37ms - 964.74msunsure 🔍
-3% - +1%
-26.48ms - +5.61ms
unsure 🔍
-2% - +1%
-21.29ms - +7.90ms
-

tachometer-reporter-action v2 for Benchmarks

@kevinpschaaf
Copy link
Member

Good start.

In addition to your notes above, also just want to add these for discussion:

  • This effectively makes the CE instance required, since it's relying on arbitrary user code doing this.dispatchEvent on the instance... I know we want to suspend constraints on an interface-only ElementRenderer while exploring, but this seems like a fundamental decision
  • This would not be compatible with loading an alternate DOM shim, since the instance would be disconnected and have no parent; to make it compatible, we'd need to do parent.appendChild(instance) and have the shim do the __eventTargetParent hookup, but it might be problematic to just randomly "append" into the parent if that's not actually where it goes (due to the desire to skip built-ins)

@justinfagnani justinfagnani changed the title Add basic event support [@lit-labs/ssr] Add basic event support Nov 30, 2021
@aomarks aomarks changed the title [@lit-labs/ssr] Add basic event support [ssr] Add basic event support Jan 19, 2022
@kevinpschaaf
Copy link
Member

Wonder if there's an alternative that would be more compatible with bring-your-own-shim and keeping the ElementRenderer just an interface where instead of requiring the instance to hook up the fake parent, we instead:

  • Add ElementRenderer:dispatchEvent (which in ours will just call instance.dispatchEvent()
  • Add a patch of dispatchEvent on whatever Element.prototype exists (either our dom shim, which would just have Element extend EventTarget, or a real DOM shim like jsdom, which would have a more correct implementation)
  • Our patch would super to the existing dispatchEvent, and then if it should bubble AND there's no this.parentNode (which is always the case in our DOM shim, and would be the case when using jsdom and you go up and hit a LitElementRenderer instance), then look in the (somehow-made-accessible) open custom elements stack and dispatch to the next element up.

It seems like that might avoid punting on ElementRenderer just yet.

We of course (maybe as part of this), should try running with a full DOM shim to make sure even the basic stuff works there, and specifically that event dispatch would work.

@EisenbergEffect
Copy link

Pinging @nicholasrice from FAST to take a look. My cursory glance leads to me to think this will work for us as well.

@nicholasrice
Copy link
Contributor

I am definitely in support of exposing dispatchEvent. The largest use-case for us will be context and dependency-injection APIs. Our DI infrastructure already is implemented using events on the client, and we have a context-like feature that could be implemented on the server using events. We also have plans to implement general-purpose context APIs, which would obviously benefit as well.

  • Can we have an event path of just the custom elements without materializing the built-ins that would be on the path with a > full DOM structure? This seems ok if the only event patterns we support are for cross-custom-element communication, ie context.

I think this constraint is suitable for our implementations and the majority of our components. It seems in-line with other code we have that no-ops operations that would provide references to native elements, such as ref directives, slotted element inspection, etc.

@justinfagnani justinfagnani changed the title [ssr] Add basic event support [labs/ssr] Add basic event support Jun 24, 2022
@aomarks aomarks mentioned this pull request Oct 13, 2022
PonomareVlad pushed a commit to PonomareVlad/lit that referenced this pull request Aug 10, 2023
PonomareVlad pushed a commit to PonomareVlad/lit that referenced this pull request Aug 10, 2023
PonomareVlad pushed a commit to PonomareVlad/lit that referenced this pull request Aug 10, 2023
PonomareVlad added a commit to PonomareVlad/lit that referenced this pull request Nov 26, 2023
@justinfagnani
Copy link
Collaborator Author

Superseded by #4755

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants