LibWeb: Add specialized fast_is for lists

Before:
  `is<HTMLOLListElement>` and other similar calls in this commit
  are resolved to `dynamic_cast`, which incurs runtime overhead
  for resolving the type. The Performance hit becomes apparent
  when rendering large lists. Callgrind analysis points to a
  significant performance hit from calls to `is<...>` in
  `Element::list_owner`.

Reference: Michael Gibbs and Bjarne Stroustrup (2006) Fast dynamic
casting. Softw. Pract. Exper. 2006; 36:139–156

After:
  Implement inline `fast_is` virtual method that immediately
  resolves the type. Results in noticeable performance improvement
  2x-ish for lists with 20K entries.

Bonus: Convert starting value for LI elements to signed integer
    The spec requires the start attribute and starting value to be
    "integer". Firefox and Chrome support a negative start attribute.

FIXME: At the time of this PR, about 134 other objects resolve
`is<...>` to `dynamic_cast`. It may be a good idea to coordinate
similar changes to at least [some of] the ones that my have impact
on performance (maybe open a new issue?).
This commit is contained in:
Manuel Zahariev 2025-04-23 07:06:11 -07:00 committed by Sam Atkins
commit d27b43c1ee
Notes: github-actions[bot] 2025-06-16 11:46:35 +00:00
7 changed files with 52 additions and 5 deletions

View file

@ -3252,7 +3252,7 @@ size_t Element::ordinal_value() const
auto reversed = false;
if (is<HTML::HTMLOListElement>(owner)) {
auto const* ol_element = static_cast<const HTML::HTMLOListElement*>(owner);
numbering = ol_element->starting_value();
numbering = ol_element->starting_value().value();
reversed = ol_element->has_attribute(HTML::AttributeNames::reversed);
}