1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 01:47:34 +00:00

LibWeb: Make StackingContext sorting a lot faster

Stacking contexts are sorted after building a tree of them. They are
sorted by z-index first, DOM tree order second.

Sorting was previously *very* slow on pages with many stacking contexts.
That was because the sort() function used Node::is_before() in the
quick_sort comparator to see if one StackingContext was before another.
is_before() does tree traversal and can take quite a long time per call.

This patch avoids all that by letting StackingContext know its index
among all StackingContexts within the same document in tree order.
There's a noticeable snappiness increase on the CSS-FLEXBOX-1 spec page,
for instance. :^)
This commit is contained in:
Andreas Kling 2023-06-02 12:01:14 +02:00
parent 500b7b08d6
commit d6c3cbd958
3 changed files with 8 additions and 5 deletions

View file

@ -28,11 +28,12 @@ static void paint_node(Layout::Node const& layout_node, PaintContext& context, P
paintable->paint(context, phase);
}
StackingContext::StackingContext(Layout::Box& box, StackingContext* parent)
StackingContext::StackingContext(Layout::Box& box, StackingContext* parent, size_t index_in_tree_order)
: m_box(box)
, m_transform(combine_transformations(m_box->computed_values().transformations()))
, m_transform_origin(compute_transform_origin())
, m_parent(parent)
, m_index_in_tree_order(index_in_tree_order)
{
VERIFY(m_parent != this);
if (m_parent)
@ -45,7 +46,7 @@ void StackingContext::sort()
auto a_z_index = a->m_box->computed_values().z_index().value_or(0);
auto b_z_index = b->m_box->computed_values().z_index().value_or(0);
if (a_z_index == b_z_index)
return a->m_box->is_before(b->m_box);
return a->m_index_in_tree_order < b->m_index_in_tree_order;
return a_z_index < b_z_index;
});