LibWeb: Retain calculated Element::ordinal_value for lists

`Element::ordinal_value` is called for every `li` element in
a list (ul, ol, menu).

Before:
  `ordinal_value` iterates through all of the children of the list
  owner. It is called once for each element: complexity $O(n^2)$.

After:
  - Save the result of the first calculation in `m_ordinal_value`
  then return it in subsequent calls.
  - Tree modifications are intercepted and trigger invalidation
    of the first node's `m_ordinal_value`:
    - insert_before
    - append
    - remove
  Results in noticeable performance improvement rendering' large
  lists: from 20s to 4s for 20K elements.
This commit is contained in:
Manuel Zahariev 2025-05-13 06:59:03 -07:00 committed by Sam Atkins
parent d27b43c1ee
commit 00d43b39d1
Notes: github-actions[bot] 2025-06-16 11:46:28 +00:00
5 changed files with 137 additions and 54 deletions

View file

@ -34,6 +34,7 @@ void HTMLLIElement::attribute_changed(FlyString const& local_name, Optional<Stri
if (local_name == HTML::AttributeNames::value) {
if (auto* owner = list_owner()) {
owner->set_needs_layout_tree_update(true, DOM::SetNeedsLayoutTreeUpdateReason::HTMLOListElementOrdinalValues);
maybe_invalidate_ordinals_for_list_owner();
}
}
}