LibWeb: Use structural sharing for CSS custom properties

Replace per-element OrderedHashMap storage for custom properties with
a RefCounted chain (CustomPropertyData) that enables structural
sharing. Each chain node stores only the properties declared directly
on its element, with a parent pointer to the inherited chain.

Elements that don't override any custom properties share the parent's
data directly (just a RefPtr copy). During cascade, only entries that
actually differ from the parent are stored in own_values - the rest
are inherited through the chain. During var() resolution, resolved
values are compared against the parent's and matching entries are
dropped, enabling further sharing.

The chain uses a depth limit (max 32) with flattening, plus
absorption of small parent nodes (threshold 8) to keep lookups fast.

This reduces custom property memory from ~79 MB to ~5.7 MB on
cloudflare.com.
This commit is contained in:
Andreas Kling
2026-02-13 10:19:02 +01:00
committed by Andreas Kling
parent 991b3d87e5
commit 9e8e568b43
Notes: github-actions[bot] 2026-02-13 13:59:49 +00:00
18 changed files with 539 additions and 67 deletions

View File

@@ -175,13 +175,12 @@ Optional<StyleProperty const&> CSSStyleProperties::custom_property(FlyString con
element.document().update_style();
auto const* element_to_check = &element;
while (element_to_check) {
if (auto property = element_to_check->custom_properties(pseudo_element).get(custom_property_name); property.has_value())
return *property;
auto data = element.custom_property_data(pseudo_element);
if (!data)
return {};
element_to_check = element_to_check->parent_element();
}
if (auto const* property = data->get(custom_property_name))
return *property;
return {};
}