Rewrite Shadow DOM v1 distribution engine on the top of a new slotchange concept

Desktop / Chromium - Hayato Ito [chromium.org] - 16 June 2017 06:54 EDT

Rewrite the core part of the Shadow DOM v1 distribution engine so that distribution recalculation happens *if and only if* a newly-defined concept of a slotchange actually happens.

Benefits:

- Performance improvement- Eliminated code complexity- Becomes spec-compliant (as a side effect, this is one of the motivations of rewriting)

1. Performance improvement:

The result of PerformanceTests/ShadowDOM performance tests:

v1-distribution-disconnected-and-reconnected Before CL: 201.4 ms After CL: 41.7 ms (5x times faster)

2. Eliminated code complexity:

Though I have a plan to explain the detail about how the v1 distribution engine works in core/dom/shadow/README.md file, let me explain the benefits of the new design here other than the performance tests:

- Eliminated false-positive for setting a dirty flag for distribution recalculation

Before this CL, the engine sets a dirty flag for distribution conservatively. As a result, a false-positive can happen, which has been difficult to avoid because distribution is not a local effect. We don't have much budget of time in DOM mutation.

After this CL, the engine sets a dirty flag if and only if a slotchange actually happens. No longer needs to set a dirty flag in other places.

Note that the engine only detects the fact of "a slotchange happens", but it doesn't try to know an exact distributed nodes for each slot at the timing of DOM mutation so that DOM mutation should not be blocked more than necessary. Distributed nodes are lazily-calculated later.

- Life cycle of slot's distribution nodes became more clear

The engine no longer clears out each slot's distributed nodes in shadow-including descendant subtrees when the subtree is disconnected from the parent tree.

e.g. We don't need to update distribution for a custom element which has deeply nested other custom elements inside of it at each insertion/removal from a tree.

The performance test's improvement came mostly from this result.

- Eliminated a lot of tricky code which is needed to support in non-shadow trees.

I successfully stopped to support in non-shadow trees, and upstreamed the decision to WHATWG DOM Standard [1], getting agreement from other browser
vendors [2]. I have already updated web platform tests [3] too. These tests no longer fail after this CL.

The support of in non-shadow trees has been difficult to support, and has been the cause of crashes. We no longer have to fight with crashes.

3. Becomes spec-compliant (as a side effect, this is one of the motivations of rewriting)

From the Web developers' perspective, this CL shouldn't have any practical impact, as long as a slot element is only used in shadow trees. The only practical visible change is:

A slotchange event is always signaled as a microtask whenever a slot's distributed nodes are changed.

For example, when a slot is inserted or removed from a tree, a slotchange event can be fired. Before this CL, a slotchange is never fired in this case. See DOM Standard issue [2] for details, which is rather a feature request from web developers. This CL satisfies this requirement, as an intended side effect.

I am aware that it would be better to separate the engine rewriting from the user
visible changes, but it would require unnecessary efforts to keep the old behavior in the new engine. Thus, I put all together. Supporting [2] is one of the reasons I decided to rewrite the engine.

Note that only Shadow DOM v1 can get these benefits. Shadow DOM v0 is out of the scope of this CL.

- [1] DOM Standard change: https://github.com/whatwg/dom/pull/459- [2] DOM Standard issue: https://github.com/whatwg/dom/issues/447- [3] Web platform tests change: https://github.com/w3c/web-platform-tests/pull/5954

Links: Change-Id: I41f29e781185c46739377ab3939d20fa24fb69bf Reviewed-on: https://chromium-review.googlesource.com/532734 Commit-Queue: Hayato Ito

27b6c95 Rewrite Shadow DOM v1 distribution engine on the top of a new slotchange concept
.../wpt/shadow-dom/slotchange-event-expected.txt | 36 ----
.../external/wpt/shadow-dom/slots-expected.txt | 26 ---
.../wpt/shadow-dom/slots-fallback-expected.txt | 13 --
.../slots-fallback-in-document-expected.txt | 5 -
.../WebKit/Source/core/dom/DocumentOrderedMap.cpp | 9 +
.../WebKit/Source/core/dom/DocumentOrderedMap.h | 3 +
third_party/WebKit/Source/core/dom/Node.cpp | 41 ++---
third_party/WebKit/Source/core/dom/Node.h | 12 +-
.../Source/core/dom/shadow/SlotAssignment.cpp | 190 +++++++++++++++------
.../WebKit/Source/core/dom/shadow/SlotAssignment.h | 18 +-
.../WebKit/Source/core/html/HTMLSlotElement.cpp | 164 +++++++++---------
.../WebKit/Source/core/html/HTMLSlotElement.h | 9 +-
12 files changed, 280 insertions(+), 246 deletions(-)

Upstream: git.chromium.org


  • Share