-
Notifications
You must be signed in to change notification settings - Fork 375
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
Shadow tree encapsulation and Element Timing #816
Comments
Using the shadow host makes the most sense to me. The principles at https://glazkov.com/2011/01/14/what-the-heck-is-shadow-dom/ still make sense to this day; things inside the shadow tree, like a slider track or thumb, are implementation details of the actually-interesting elements, i.e. the shadow hosts. |
@domenic, what do you mean by using the shadow host? I think what makes the most sense, given that we now have |
I meant
I agree we could have something that allows more complicated delegation, but for the cases where shadow DOM is being used to encapsulate internal implementation details (like the range input in Dimitri's blog post), the timing of the element as a whole (as represented by the shadow host) is more interesting than the timing of any individual piece. |
So where are the entries exposed? I thought it was a global method/getter? |
For the purpose of element timing, elements with shadow trees should be treated like any builtin element with shadow trees. Given element timing currently only supports measuring Since elements inside shadow trees are considered as implementation details, no element marked with |
The entries are exposed to PerformanceObserver. An observer can receive entries from elements corresponding to its Window. Maybe it's worth clarifying how entries are created right now. I recently updated the explainer: there's an entry per image, per background-image (per affected element), and per group of text nodes (for example, to try to group text nodes belonging to a single paragraph under the same p element). Exposing a single entry for each shadow tree could be an option, though it seems incomparable with these other entries. I'm also unsure how we'd define the time the shadow tree is 'ready': when all of the images and text nodes associated with it are ready?
We're also adding support for groups of text nodes (grouped under a single element).
So the only options are aggregating entries into an entry per shadow tree (I guess not including nested shadow trees, I'm not sure if there's a name for this), or omitting any entries of shadow trees altogether? |
We initially exposed these elements but this seems to break design invariants. It is still unclear what we can do with elements in shadow trees, but for now it is safest to not expose them at all. Relevant threads: WICG/element-timing#3 WICG/webcomponents#816 Bug: 879270 Change-Id: Id4c0d65e0f0e086c6c6dfa29cc019a4c1ef6ab1f
We need to omit any entry originating within a shadow tree. We consider being able to detect that there is a shadow tree as a bug / undesirable as well. |
I don't understand what you mean by that. If I attached a shadow root to one of my elements, how would I not know that there is a shadow tree? |
Things inside a shadow tree shouldn't leak outside the shadow tree is the general principle. For that reason, if element timing was done inside a shadow tree, then those entries shouldn't be globally visible. |
As an author of applications built with web compoments and shadow dom, I would hate to lose out on being able to use the element timing API at all. |
You would, unless there's a way for a custom element to expose element timing somehow. (Similar to how your custom element can become form-associated.) |
So why is having elementtiming attribute set not explicit enough then? |
Because we don't want to leak the details of the shadow tree as that might lead to the light tree taking dependencies on details that ought to be changeable. That's what the encapsulation is for. |
Ok, so what do you propose for a |
We initially exposed these elements but this seems to break design invariants. It is still unclear what we can do with elements in shadow trees, but for now it is safest to not expose them at all. Relevant threads: WICG/element-timing#3 WICG/webcomponents#816 Bug: 879270 Change-Id: Id4c0d65e0f0e086c6c6dfa29cc019a4c1ef6ab1f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1622470 Reviewed-by: Chris Harrelson <[email protected]> Commit-Queue: Nicolás Peña Moreno <[email protected]> Cr-Commit-Position: refs/heads/master@{#662391}
We initially exposed these elements but this seems to break design invariants. It is still unclear what we can do with elements in shadow trees, but for now it is safest to not expose them at all. Relevant threads: WICG/element-timing#3 WICG/webcomponents#816 Bug: 879270 Change-Id: Id4c0d65e0f0e086c6c6dfa29cc019a4c1ef6ab1f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1622470 Reviewed-by: Chris Harrelson <[email protected]> Commit-Queue: Nicolás Peña Moreno <[email protected]> Cr-Commit-Position: refs/heads/master@{#662391}
I would expect it to be something similar to form-associated custom elements, which recently landed in the HTML Standard. You might wanna reach out to @tkent-google. |
We discussed this briefly during the conference call this week. Apparently @tkent-google has suggested two alternatives:
I objected to (2) since it breaks the encapsulation of shadow roots. Another alternative I suggested would be making |
I think for complex use cases like ours, where we have components from multiple authors running in the same page and the elements to be loaded are "somewhat unknown" until runtime, passing a fixed set to the Observer API will be tricky. So having a flag either on attachShadow on in ElementInternals would be preferable since it will give us holistic control (assuming shadow creation has an abstraction, which most frameworks do).
@rniwa would you object even if the flag will make the observability opaque? Basically something similar to what @domenic suggested: if I flag a shadow to be "perf-observable", whatever is reported is tied to the custom-element and none of the internals, So any marked image or svg inside (not sure about light-shadow), will be aggregated an reported as it was in the host custom element.
As a final though, we would love to see this implemented whatever way makes encapsulation and implementors happy :) |
Could someone explain what the problems are with taking the same approach as with form-associated custom elements? I suggested that and since then folks have mentioned alternatives, but not provided rationale for why those alternatives are better. |
The main reason is that this is about shadow DOM, not custom elements. The problem can occur with no custom elements in sight, so a custom elements specific solution would not be helpful in those cases. |
I guess I'll reiterate that I think allowing shadow roots and non-custom elements was a mistake. We'll keep running into this if we decide those are as important as custom elements. (That is, |
Can you explain why it breaks encapsulation? If the flag is passed, the component author has agreed to expose the performance information.
As @diervo mentioned this is not a scalable solution for the Element Timing case.
If folks are fine declaring that shadow DOM should never be used without custom elements, then that seems fine to me. However, given opt in from the custom element, can't we expose the information to the PerformanceObservers of the window? That is, both the component author and the component user should be able to look at the information with the opt in from the component author. |
Because it leaks nodes inside a shadow tree. In general, we don't provide that kind of opt-in. Opt-in we have deciding whether |
Ok, maybe we should split this into two questions:
|
Right, those are two distinct scenarios. Note that in the case of nested shadow roots, mechanism for (2) must be used in conjunction with (1) because a shadow host which resides inside another shadow root must not be exposed to the global object. There needs to be an explicit opt-in mechanism for the author of shadow root in such a case, or some kind of propagation from shadow tree to the shadow host as we do for focus; e.g. if an element E1 inside a shadow tree S1 inside another shadow root S2 is focused, then E1 is exposed as |
I've been thinking about this a lot over the last week and arrived at a point that I'd like some feedback on. Which is, perhaps open/closed shadow DOM is the right switch for this. First, consider that with a scoped-to-the-shadow-DOM solution plus open shadow DOM, you could always do tree traversal to access the information, it would just be more awkward. In the past, we've decided to leave things like this awkward (e.g. finding the "real" activeElement requires tree traversal), but perhaps for monitoring-type performance APIs, we should allow the information to accumulate without the extra code. Second, consider how we're seeing shadow DOM (and perhaps web components more generally) in use today. I see two main uses:
I claim that (1) benefits from strong encapsulation, even for performance monitoring APIs. If you're using a neato date picker, and the month dropdown is slow, you (the app author) don't actually want to know about the month dropdown. You just want to know that the date picker component you're using is slow. This is similar to browser built-ins: app developers don't care what implementation detail of Whereas (2) is more using encapsulation as a convenience, mostly for the style encapsulation. The boundaries are looser, and open shadow DOM is usually used, permitting them to be crossed if it's expedient or necessary for the app developer. In these cases, when you're using shadow DOM as an app-level component framework, it'd be nicer if performance monitoring APIs were able to peek into your app's shadow DOM, preferably without tree traversal + aggregation code. I'm curious if this makes any sense to others. Although I've always been interested in web components for (1), I think we have to recognize that a lot of authors like using it for (2). Saying that you can't get performance data inside a shadow DOM, even an open shadow DOM, without extensive back and forth, seems like it would drive authors away from either performance APIs or from (2). |
@domenic I can concur from a real usage perspective. At ING we've been using web components for the past 3 years doing both (1) and (2). We have a web component based design system for leaf components, buttons and date pickers etc. But we also use web components all the way up the tree as a component model for higher level components. Both are built by different teams with a different focus/specialty and with different requirements. For the higher level components style encapsulation is the primary reason for using shadow dom, so that different teams can easily distribute components including styles. Losing out on things like element performance timing because of that would be a shame. To me closed/open shadow roots always seemed like the intended way to differentiate between the two use cases. |
I don't think exposing nodes in a shadow root without users of the API explicitly requesting nodes inside the shadow root is acceptable. Consider The problem here is that the existing scripts and code that uses the performance timeline to aggregate information, for example, shouldn't be encountering a node inside a shadow tree. That goes against the goal of avoiding accidental encountering of nodes within a shadow tree. In general, nodes in an open or closed shadow tree should never be exposed to API on To reiterate my point earlier, at minimum, we need to an explicit method on |
The existing clients concern is exactly the sort of feedback I was hoping for; thank you @rniwa. I agree that if we were to allow easy (no manual tree traversal) code for getting performance entries in open shadow trees, the page author collecting those entries should explicitly opt in to it. |
…n Shadow Trees, a=testonly Automatic update from web-platform-tests [ElementTiming] Do not expose elements in Shadow Trees We initially exposed these elements but this seems to break design invariants. It is still unclear what we can do with elements in shadow trees, but for now it is safest to not expose them at all. Relevant threads: WICG/element-timing#3 WICG/webcomponents#816 Bug: 879270 Change-Id: Id4c0d65e0f0e086c6c6dfa29cc019a4c1ef6ab1f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1622470 Reviewed-by: Chris Harrelson <[email protected]> Commit-Queue: Nicolás Peña Moreno <[email protected]> Cr-Commit-Position: refs/heads/master@{#662391} -- wp5At-commits: 6272cd07e39bf7c67f58f30db41568033355b1dd wpt-pr: 16939
…n Shadow Trees, a=testonly Automatic update from web-platform-tests [ElementTiming] Do not expose elements in Shadow Trees We initially exposed these elements but this seems to break design invariants. It is still unclear what we can do with elements in shadow trees, but for now it is safest to not expose them at all. Relevant threads: WICG/element-timing#3 WICG/webcomponents#816 Bug: 879270 Change-Id: Id4c0d65e0f0e086c6c6dfa29cc019a4c1ef6ab1f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1622470 Reviewed-by: Chris Harrelson <[email protected]> Commit-Queue: Nicolás Peña Moreno <[email protected]> Cr-Commit-Position: refs/heads/master@{#662391} -- wp5At-commits: 6272cd07e39bf7c67f58f30db41568033355b1dd wpt-pr: 16939
We initially exposed these elements but this seems to break design invariants. It is still unclear what we can do with elements in shadow trees, but for now it is safest to not expose them at all. Relevant threads: WICG/element-timing#3 WICG/webcomponents#816 Bug: 879270 Change-Id: Id4c0d65e0f0e086c6c6dfa29cc019a4c1ef6ab1f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1622470 Reviewed-by: Chris Harrelson <[email protected]> Commit-Queue: Nicolás Peña Moreno <[email protected]> Cr-Commit-Position: refs/heads/master@{#662391}
As I understand, the element timing spec has been updated to reflect the discussion here to not expose elements within shadow trees. Closing this issue for now. |
Did I miss a resolution to the fundamental problem here? There seems to be no way to measure performance within shadow DOM, even if the author of the shadow tree wants to opt in. There are many instances where this seems desirable, for instance when web components encapsulate a web app. I don't think this should be closed, unless that problem is tracked elsewhere. |
Please file a new issue to track that. |
We're incubating the ElementTiming API which exposes rendering timings of elements of a website (namely, image and text content). I filed internally WICG/element-timing#3 to attempt to clarify what the interaction with shadow elements should be (in particular regarding what we can expose from the shadow tree). I realize that an issue there will not be noticed by relevant folks so I figure I can get more attention by filing an issue here.
I understand that there is a desire to have some encapsulation principles. Where are those principles stated? I'd be interested to understand the motivations of them. In this particular case, I'm interested in understanding if/why it would be desirable to hide important performance information from developers when they use shadow trees. I stated some options on how to handle in the other issue, restating here:
element
set to null.element
attribute value to the shadow host / shadow root.CC people on the other issue @hayatoito @annevk
The text was updated successfully, but these errors were encountered: