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.
- 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
I successfully stopped to support
vendors . I have already updated web platform tests  too. These tests no longer fail after this CL.
The support of
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  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  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.
-  DOM Standard change: https://github.com/whatwg/dom/pull/459-  DOM Standard issue: https://github.com/whatwg/dom/issues/447-  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(-)