Commit e8b6d22b authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

Allow style recalc roots in shadow trees.

When we mark the light tree ancestors child-dirty for style, we could
not set a node inside a shadow scope as a style recalc root because
slotted nodes could require traversal via the host light tree parent.
With FlatTreeStyleRecalc enabled, we can now allow that.

This affected performance for the perf_test below because the elements
needing recalc where light-tree children of a shadow host high up the
light-tree which were slotted deep into the chain of shadow hosts with
slots. With the recalc root in the document scope, that made us traverse
deep in the flat tree to reach the dirty nodes, while the light-tree
traversal would skip the shadow trees and recalc the styles for the
dirty nodes as part of the light tree children of the outer shadow host.

It's not certain this makes all the perf regression recover, but local
testing shows that it definitely improves.

TEST=perf_tests/shadow_dom/v1-mutate-shallow-tree-then-re-layout.html

Bug: 1023215
Change-Id: Id7143bf0e8fd7c298d6b683be8ead0fd23941f4b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1912711Reviewed-by: default avatarMason Freed <masonfreed@chromium.org>
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Cr-Commit-Position: refs/heads/master@{#714981}
parent 79bbf04a
......@@ -2397,4 +2397,23 @@ TEST_F(StyleEngineTest, MoveSlottedOutsideFlatTreeCrash) {
EXPECT_EQ(host2, GetStyleRecalcRoot());
}
TEST_F(StyleEngineTest, StyleRecalcRootInShadowTree) {
ScopedFlatTreeStyleRecalcForTest feature_scope(true);
GetDocument().body()->SetInnerHTMLFromString(R"HTML(
<div id="host"></div>
)HTML");
Element* host = GetDocument().getElementById("host");
ShadowRoot& shadow_root =
host->AttachShadowRootInternal(ShadowRootType::kOpen);
shadow_root.SetInnerHTMLFromString("<div><span></span></div>");
UpdateAllLifecyclePhases();
Element* span = To<Element>(shadow_root.firstChild()->firstChild());
// Mark style dirty.
span->SetInlineStyleProperty(CSSPropertyID::kColor, "blue");
EXPECT_EQ(span, GetStyleRecalcRoot());
}
} // namespace blink
......@@ -21,18 +21,20 @@ Element& StyleRecalcRoot::RootElement() const {
// originating element for simplicity.
return *root_node->parentElement();
}
if (!RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled()) {
if (root_node->IsInShadowTree()) {
// Since we traverse in light tree order, we might need to traverse slotted
// shadow host children for inheritance for which the recalc root is not an
// ancestor. Since we might re-slot slots, we need to start at the outermost
// shadow host.
// Since we traverse in light tree order, we might need to traverse
// slotted shadow host children for inheritance for which the recalc root
// is not an ancestor. Since we might re-slot slots, we need to start at
// the outermost shadow host.
TreeScope* tree_scope = &root_node->GetTreeScope();
while (!tree_scope->ParentTreeScope()->RootNode().IsDocumentNode())
tree_scope = tree_scope->ParentTreeScope();
return To<ShadowRoot>(tree_scope->RootNode()).host();
}
}
if (root_node->IsTextNode())
return *root_node->parentElement();
root_node = root_node->GetStyleRecalcParent();
return To<Element>(*root_node);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment