Intent to Ship: Declarative Shadow DOM

288 views
Skip to first unread message

Mason Freed

unread,
Feb 18, 2021, 6:19:17 PM2/18/21
to blink-dev

Contact emails

mason...@chromium.org

Explainer


https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md
https://web.dev/declarative-shadow-dom/

Specification

https://github.com/whatwg/html/pull/5465

API spec

Yes

Design docs


https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md

Summary

A declarative API to allow the creation of #shadowroot's using only HTML and no Javascript. Sign up for an Origin Trial (M85-M89) here: https://developers.chrome.com/origintrials/#/register_trial/2024368032503037953 Blog post: https://web.dev/declarative-shadow-dom/



Blink component

Blink>DOM>ShadowDOM

Search tags

Shadow DOMDeclarative

TAG review

https://github.com/w3ctag/design-reviews/issues/494

TAG review status

Issues addressed

Link to origin trial feedback summary

https://docs.google.com/document/d/1QmBKxQLE81PsMzyPCvYhzqRAn4hxz61Jzk0uXJAhaVc

Risks



Interoperability and Compatibility

The main interoperability risk would be that other browsers fail to implement this API. This feature is quite polyfillable, so it should still be usable while other implementations are being completed.



Gecko: Non-harmful (https://github.com/mozilla/standards-positions/issues/335#issuecomment-668875898) Some concern that the feature "doesn't carry its weight", but Firefox considers this API non-harmful. Many offline discussions were had, with many issues discussed. A summary of the current state can be found here: https://github.com/mozilla/standards-positions/issues/335#issuecomment-781697858

WebKit: No signal (https://lists.webkit.org/pipermail/webkit-dev/2020-August/031331.html) WebKit has been pinged several times, with nearly no response. rniwa@ did tweet some mildly-supportive (but obviously not "official") comments: https://twitter.com/rniwa_dev/status/1309582835234172928 https://twitter.com/rniwa_dev/status/1352322006448947203

Web developers: Positive See many comments from developers on the prior thread resolving *not* to move forward with declarative Shadow DOM. Most are positive and want a solution to this problem. Start after this comment: https://github.com/whatwg/dom/issues/510#issuecomment-370980398

Ergonomics

Much thought has been given to the ergonomics of this API. A more ergonomic alternative, that of a new <shadowroot> element, would create significant web compat problems for browsers that do not yet support the new element. The biggest risk of the current proposal is that it does not *also* solve the declarative adoptedStylesheets problem. That is, to include stylesheets within declarative shadowroots, inline <style> elements must be used. That isn't as large of a penalty as it would seem, but it is a stumbling block. See https://github.com/whatwg/dom/issues/831#issuecomment-585451735, point #3 for more discussion of this issue.



Activation

This feature is rather polyfillable - see https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md#feature-detection-and-polyfilling. However, any such polyfill would require Javascript to work, and the primary motivation for this feature is no-JS SSR. However, for sites that want to use Web Components and Shadow DOM, it would seem that such a polyfill could be written in a way that does not impact performance for browsers that have implemented this proposal, and does no worse for browsers that have not yet supported this API.



Security

The prior implementation of <template> caused significant parser security issues. While this proposal attempts to re-use as much as possible of the existing <template> implementation, there are a few required changes. It is possible that those changes introduce new security holes. Additionally, the existing implementation of <template> could also still contain undiscovered security problems. There is a specific concern that has been identified for existing (non-upgraded, old) XSS sanitizer libraries. This concern has been mitigated by creating an opt-in mechanism for the fragment parser. There is an extensive discussion of this issue in the explainer (https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md#security-and-privacy-considerations) and in the #912 issue thread (https://github.com/whatwg/dom/issues/912).



Debuggability

Since this is a parser-only feature, parsed DOM content will contain only "normal" #shadowroot nodes. Devtools already fully supports Shadow DOM, and all of those existing tools will continue to apply to this new method of declaratively creating Shadow DOM.



Is this feature fully tested by web-platform-tests?

Yes

Tracking bug

https://crbug.com/1042130

Launch bug

https://crbug.com/1141102

Sample links


https://jsbin.com/huquloz

Link to entry on the Chrome Platform Status

https://chromestatus.com/feature/5191745052606464

Links to previous Intent discussions

Intent to prototype: https://groups.google.com/a/chromium.org/d/msg/blink-dev/nJDc-1s3R9U/uCJKsEqpAwAJ
Intent to Experiment: https://groups.google.com/a/chromium.org/d/msg/blink-dev/DuvhXyYo7Pc/_zcDVQmCAAAJ


This intent message was generated by Chrome Platform Status.

yo...@yoav.ws

unread,
Feb 23, 2021, 5:27:39 PM2/23/21
to blink-dev, Mason Freed
https://github.com/whatwg/dom/issues/831#issuecomment-718534647 seems rather negative on a streaming requirement. Is that an issue?

Mason Freed

unread,
Feb 23, 2021, 6:40:47 PM2/23/21
to yo...@yoav.ws, blink-dev
On Tue, Feb 23, 2021 at 2:27 PM yo...@yoav.ws <yo...@yoav.ws> wrote:

https://github.com/whatwg/dom/issues/831#issuecomment-718534647 seems rather negative on a streaming requirement. Is that an issue?

That's a good question. There's been significant discussion about streaming vs. non-streaming declarative Shadow DOM. (The streaming version would parse shadow root contents directly into a newly-created shadow root, as they're parsed. The current proposal/implementation is non-streaming: we parse into an inert DocumentFragment, and then move contents over to the shadow root upon the closing </template> tag.) The comment you reference is the primary reason we've gone with the non-streaming solution: WebKit is quite opposed to such a solution, because of the potential for security issues. Security issues were encountered for years after the implementation of <template>, and there is a desire not to repeat that. So I actually see the referenced comment as supportive of this aspect of the current proposal.

Yoav Weiss

unread,
Feb 24, 2021, 6:59:19 AM2/24/21
to Mason Freed, blink-dev
On Wed, Feb 24, 2021 at 12:40 AM Mason Freed <mason...@chromium.org> wrote:


On Tue, Feb 23, 2021 at 2:27 PM yo...@yoav.ws <yo...@yoav.ws> wrote:

https://github.com/whatwg/dom/issues/831#issuecomment-718534647 seems rather negative on a streaming requirement. Is that an issue?

That's a good question. There's been significant discussion about streaming vs. non-streaming declarative Shadow DOM. (The streaming version would parse shadow root contents directly into a newly-created shadow root, as they're parsed. The current proposal/implementation is non-streaming: we parse into an inert DocumentFragment, and then move contents over to the shadow root upon the closing </template> tag.) The comment you reference is the primary reason we've gone with the non-streaming solution: WebKit is quite opposed to such a solution, because of the potential for security issues. Security issues were encountered for years after the implementation of <template>, and there is a desire not to repeat that.

That sounds perfectly reasonable.
 
So I actually see the referenced comment as supportive of this aspect of the current proposal.

Makes sense.

Yoav Weiss

unread,
Feb 24, 2021, 9:03:53 AM2/24/21
to Mason Freed, blink-dev
On Wed, Feb 24, 2021 at 12:58 PM Yoav Weiss <yo...@yoav.ws> wrote:


On Wed, Feb 24, 2021 at 12:40 AM Mason Freed <mason...@chromium.org> wrote:


On Tue, Feb 23, 2021 at 2:27 PM yo...@yoav.ws <yo...@yoav.ws> wrote:

https://github.com/whatwg/dom/issues/831#issuecomment-718534647 seems rather negative on a streaming requirement. Is that an issue?

That's a good question. There's been significant discussion about streaming vs. non-streaming declarative Shadow DOM. (The streaming version would parse shadow root contents directly into a newly-created shadow root, as they're parsed. The current proposal/implementation is non-streaming: we parse into an inert DocumentFragment, and then move contents over to the shadow root upon the closing </template> tag.) The comment you reference is the primary reason we've gone with the non-streaming solution: WebKit is quite opposed to such a solution, because of the potential for security issues. Security issues were encountered for years after the implementation of <template>, and there is a desire not to repeat that.

That sounds perfectly reasonable.

Having read through the TAG review and streaming discussion, I want to make sure I properly understand: if/when we realize that the performance penalty of not streaming DSD is significant (e.g. for the `<app></app>` case or for large page components), what would be the path to adding such streaming support? Would that just be a spec & implementation change? Would content need to opt-in?

Mason Freed

unread,
Feb 24, 2021, 5:43:30 PM2/24/21
to Yoav Weiss, blink-dev
On Wed, Feb 24, 2021 at 6:03 AM Yoav Weiss <yo...@yoav.ws> wrote:

Having read through the TAG review and streaming discussion, I want to make sure I properly understand: if/when we realize that the performance penalty of not streaming DSD is significant (e.g. for the `<app></app>` case or for large page components), what would be the path to adding such streaming support? Would that just be a spec & implementation change? Would content need to opt-in?

So there are two answers to this question:
  1.  The technical answer: to add streaming support, it could be as easy as adding an attribute: <template shadowroot=open streaming>. If the "streaming" attribute is present on the opening tag, the browser can construct the Shadow Root immediately, and begin streaming contents directly. If the attribute is not present, the existing behavior will be used. I do believe we'd need to make it opt-in, to avoid compat issues. I suppose that remains to be seen, at the time we propose the addition of streaming. But...
  2. The cross-browser answer: this comment on the TAG review sums it up pretty well. WebKit is strongly opposed to any streaming solution. And Gecko is against a "streaming optional" solution. So I'm not sure there's a path forward for an interoperable streaming DSD solution, unfortunately. Perhaps that situation will change once this feature ships and starts to gain traction.

Christian Biesinger

unread,
Feb 25, 2021, 7:14:14 AM2/25/21
to Mason Freed, Yoav Weiss, blink-dev
On Wed, Feb 24, 2021 at 11:43 PM Mason Freed <mason...@chromium.org> wrote:
>
>
>
> On Wed, Feb 24, 2021 at 6:03 AM Yoav Weiss <yo...@yoav.ws> wrote:
>>
>>
>> Having read through the TAG review and streaming discussion, I want to make sure I properly understand: if/when we realize that the performance penalty of not streaming DSD is significant (e.g. for the `<app></app>` case or for large page components), what would be the path to adding such streaming support? Would that just be a spec & implementation change? Would content need to opt-in?
>
>
> So there are two answers to this question:
>
> The technical answer: to add streaming support, it could be as easy as adding an attribute: <template shadowroot=open streaming>. If the "streaming" attribute is present on the opening tag, the browser can construct the Shadow Root immediately, and begin streaming contents directly. If the attribute is not present, the existing behavior will be used. I do believe we'd need to make it opt-in, to avoid compat issues. I suppose that remains to be seen, at the time we propose the addition of streaming. But...
> The cross-browser answer: this comment on the TAG review sums it up pretty well. WebKit is strongly opposed to any streaming solution. And Gecko is against a "streaming optional" solution. So I'm not sure there's a path forward for an interoperable streaming DSD solution, unfortunately. Perhaps that situation will change once this feature ships and starts to gain traction.

I'm not so familiar with the discussions; could you briefly summarize
what the security issues with streaming are? Thanks!

Christian
> --
> You received this message because you are subscribed to the Google Groups "blink-dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
> To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CAM%3DNeDjRCOYCR387%2B2vrVmtV55SqUw0X0FU_%3DOpx171LqFBGzA%40mail.gmail.com.

Yoav Weiss

unread,
Feb 25, 2021, 3:25:18 PM2/25/21
to Christian Biesinger, Mason Freed, blink-dev
LGTM1

I'm excited about this enabling faster Web Components. I'm less excited about the lack of streaming, but there seems to be clear tension between that and future interoperability. As such, I'll take a future path towards making DSD streaming, in case we'll see the lack of streaming being a bottleneck.

Mason Freed

unread,
Feb 25, 2021, 7:12:32 PM2/25/21
to Christian Biesinger, Yoav Weiss, blink-dev
On Thu, Feb 25, 2021 at 4:14 AM Christian Biesinger <cbies...@chromium.org> wrote:

I'm not so familiar with the discussions; could you briefly summarize
what the security issues with streaming are? Thanks!

Sure! The basic concern revolves around the many places that the parser needs to have "special" behavior. The comparison that is often made is to the implementation of the <template> element, because the model is similar: the contents of <template> are parsed into a separate document, rather than directly into the tree. This required many special cases to be added to the parser. While I was not involved in the implementation of <template>, the story is that there was a long tail of security bugs related to these special cases (missing ones, or extra ones) that took ~years to sort out. The view from WebKit is that we don't want to repeat this pain. Personally, I think the example of <template> can be used to avoid most (but likely not all) of that pain, since each of those special case points can be used as a model for the implementation of the streaming declarative Shadow DOM.

Thanks,
Mason

Mason Freed

unread,
Feb 25, 2021, 7:15:52 PM2/25/21
to Yoav Weiss, Christian Biesinger, blink-dev
On Thu, Feb 25, 2021 at 12:25 PM Yoav Weiss <yo...@yoav.ws> wrote:
LGTM1

I'm excited about this enabling faster Web Components. I'm less excited about the lack of streaming, but there seems to be clear tension between that and future interoperability. As such, I'll take a future path towards making DSD streaming, in case we'll see the lack of streaming being a bottleneck.

Thanks! I am similarly disappointed that we couldn't manage streaming now. But much of the overall pushback (from other implementers) is based on a lack of understanding about how it will be used, and what benefits it will offer. So landing this now and starting that learning process will be a good way to see if streaming is truly needed.

Thanks,
Mason

TAMURA, Kent

unread,
Feb 25, 2021, 7:24:33 PM2/25/21
to Mason Freed, blink-dev, Yoav Weiss, Christian Biesinger
LGTM2




--
TAMURA Kent
Software Engineer, Google


Mike West

unread,
Feb 26, 2021, 6:54:48 AM2/26/21
to blink-dev, Kent Tamura, yo...@yoav.ws, Christian Biesinger, Mason Freed
LGTM3. I'd like to note that I particularly appreciate the way y'all worked with various security teams' feedback around sanitizers. Thank you.

Mason Freed

unread,
Feb 26, 2021, 11:45:58 AM2/26/21
to Mike West, blink-dev, Kent Tamura, yo...@yoav.ws, Christian Biesinger
On Fri, Feb 26, 2021 at 3:54 AM Mike West <mk...@chromium.org> wrote:
LGTM3. I'd like to note that I particularly appreciate the way y'all worked with various security teams' feedback around sanitizers. Thank you.

On Friday, February 26, 2021 at 1:24:33 AM UTC+1 Kent Tamura wrote:
LGTM2

Thanks for both of these!

Thanks,
Mason
Reply all
Reply to author
Forward
0 new messages