LibWeb: Avoid ref-count churn when diffing computed styles

This commit is contained in:
Tim Ledbetter
2026-04-24 16:18:40 +01:00
committed by Andreas Kling
parent 5d38e37a53
commit eef11001ec
Notes: github-actions[bot] 2026-04-25 06:49:15 +00:00
3 changed files with 12 additions and 7 deletions

View File

@@ -15,7 +15,7 @@
namespace Web::CSS { namespace Web::CSS {
static bool is_stacking_context_creating_value(CSS::PropertyID property_id, RefPtr<StyleValue const> const& value) static bool is_stacking_context_creating_value(CSS::PropertyID property_id, StyleValue const* value)
{ {
if (!value) if (!value)
return false; return false;
@@ -59,12 +59,14 @@ static bool is_stacking_context_creating_value(CSS::PropertyID property_id, RefP
} }
} }
RequiredInvalidationAfterStyleChange compute_property_invalidation(CSS::PropertyID property_id, ValueComparingRefPtr<StyleValue const> const& old_value, ValueComparingRefPtr<StyleValue const> const& new_value) RequiredInvalidationAfterStyleChange compute_property_invalidation(CSS::PropertyID property_id, StyleValue const* old_value, StyleValue const* new_value)
{ {
RequiredInvalidationAfterStyleChange invalidation; RequiredInvalidationAfterStyleChange invalidation;
if (old_value == new_value) if (old_value == new_value)
return invalidation; return invalidation;
if (old_value && new_value && old_value->equals(*new_value))
return invalidation;
// NOTE: If the computed CSS display, position, content, or content-visibility property changes, we have to rebuild the entire layout tree. // NOTE: If the computed CSS display, position, content, or content-visibility property changes, we have to rebuild the entire layout tree.
// In the future, we should figure out ways to rebuild a smaller part of the tree. // In the future, we should figure out ways to rebuild a smaller part of the tree.

View File

@@ -31,6 +31,6 @@ struct RequiredInvalidationAfterStyleChange {
static RequiredInvalidationAfterStyleChange full() { return { true, true, true, true, false }; } static RequiredInvalidationAfterStyleChange full() { return { true, true, true, true, false }; }
}; };
RequiredInvalidationAfterStyleChange compute_property_invalidation(CSS::PropertyID property_id, ValueComparingRefPtr<StyleValue const> const& old_value, ValueComparingRefPtr<StyleValue const> const& new_value); RequiredInvalidationAfterStyleChange compute_property_invalidation(CSS::PropertyID property_id, StyleValue const* old_value, StyleValue const* new_value);
} }

View File

@@ -850,8 +850,11 @@ static CSS::RequiredInvalidationAfterStyleChange compute_required_invalidation(C
for (auto i = to_underlying(CSS::first_longhand_property_id); i <= to_underlying(CSS::last_longhand_property_id); ++i) { for (auto i = to_underlying(CSS::first_longhand_property_id); i <= to_underlying(CSS::last_longhand_property_id); ++i) {
auto property_id = static_cast<CSS::PropertyID>(i); auto property_id = static_cast<CSS::PropertyID>(i);
auto const& old_value = old_style.property(property_id);
invalidation |= CSS::compute_property_invalidation(property_id, old_style.property(property_id), new_style.property(property_id)); auto const& new_value = new_style.property(property_id);
if (&old_value == &new_value)
continue;
invalidation |= CSS::compute_property_invalidation(property_id, &old_value, &new_value);
} }
// NB: Even if the computed value hasn't changed the resolved counter style may have (e.g. if the relevant // NB: Even if the computed value hasn't changed the resolved counter style may have (e.g. if the relevant
@@ -1068,7 +1071,7 @@ CSS::RequiredInvalidationAfterStyleChange Element::recompute_inherited_style()
RefPtr new_value = CSS::StyleComputer::get_non_animated_inherit_value(property_id, { *this }); RefPtr new_value = CSS::StyleComputer::get_non_animated_inherit_value(property_id, { *this });
computed_properties->set_property(property_id, *new_value, CSS::ComputedProperties::Inherited::Yes); computed_properties->set_property(property_id, *new_value, CSS::ComputedProperties::Inherited::Yes);
invalidation |= CSS::compute_property_invalidation(property_id, old_value, computed_properties->property(property_id)); invalidation |= CSS::compute_property_invalidation(property_id, old_value.ptr(), &computed_properties->property(property_id));
} }
if (invalidation.is_none() && property_values_affected_by_inherited_style.is_empty()) if (invalidation.is_none() && property_values_affected_by_inherited_style.is_empty())
@@ -1080,7 +1083,7 @@ CSS::RequiredInvalidationAfterStyleChange Element::recompute_inherited_style()
for (auto const& [property_id, old_value] : property_values_affected_by_inherited_style) { for (auto const& [property_id, old_value] : property_values_affected_by_inherited_style) {
auto const& new_value = computed_properties->property(static_cast<CSS::PropertyID>(property_id)); auto const& new_value = computed_properties->property(static_cast<CSS::PropertyID>(property_id));
invalidation |= CSS::compute_property_invalidation(static_cast<CSS::PropertyID>(property_id), old_value, new_value); invalidation |= CSS::compute_property_invalidation(static_cast<CSS::PropertyID>(property_id), old_value.ptr(), &new_value);
} }
if (invalidation.is_none()) if (invalidation.is_none())