commit 6cb49e422cad3e0bba008296df7d5929b25e8b43
parent 04b013b47241e496684d5f7eb4368c0898166d87
Author: Denis Palmeiro <dpalmeiro@mozilla.com>
Date: Tue, 30 Dec 2025 15:43:10 +0000
Bug 2006172: Allow style sharing across shadow hosts. r=emilio,firefox-style-system-reviewers
Allow shadow hosts to share styles when they have the same CascadeData pointer,
ensuring they have the same :host rules. Improves TodoMVC-WebComponents by ~10%.
Differential Revision: https://phabricator.services.mozilla.com/D277357
Diffstat:
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/servo/components/style/sharing/mod.rs b/servo/components/style/sharing/mod.rs
@@ -68,7 +68,7 @@ use crate::applicable_declarations::ApplicableDeclarationBlock;
use crate::bloom::StyleBloom;
use crate::computed_value_flags::ComputedValueFlags;
use crate::context::{SharedStyleContext, StyleContext};
-use crate::dom::{SendElement, TElement};
+use crate::dom::{SendElement, TElement, TShadowRoot};
use crate::properties::ComputedValues;
use crate::rule_tree::StrongRuleNode;
use crate::selector_map::RelevantAttributes;
@@ -654,16 +654,6 @@ impl<E: TElement> StyleSharingCache<E> {
return;
}
- // We can't share style across shadow hosts right now, because they may
- // match different :host rules.
- //
- // TODO(emilio): We could share across the ones that don't have :host
- // rules or have the same.
- if element.shadow_root().is_some() {
- debug!("Failing to insert into the cache: Shadow Host");
- return;
- }
-
// If the element has running animations, we can't share style.
//
// This is distinct from the specifies_{animations,transitions} check below,
@@ -817,9 +807,18 @@ impl<E: TElement> StyleSharingCache<E> {
return None;
}
- if target.element.shadow_root().is_some() {
- trace!("Miss: Shadow host");
- return None;
+ // Shadow hosts can share style when they have matching CascadeData pointers, which
+ // ensures they match the same :host rules.
+ match (
+ target.element.shadow_root().and_then(|s| s.style_data()),
+ candidate.element.shadow_root().and_then(|s| s.style_data()),
+ ) {
+ (Some(td), Some(cd)) if std::ptr::eq(td, cd) => {},
+ (None, None) => {},
+ _ => {
+ trace!("Miss: Different shadow root style data");
+ return None;
+ },
}
if target.element.has_animations(shared_context)