LibWeb: Don't traverse entire layout tree in every HTML::EventLoop tick

Instead, collect a list of all the elements with content-visibility:auto
after layout.

This way we can skip the tree traversal when updating the rendering.

This was previously eating up ~300 µs of the 60fps frame budget on
our GitHub repo pages (and even more on large pages).
This commit is contained in:
Andreas Kling 2025-06-11 10:44:44 +02:00 committed by Andreas Kling
commit 07ff75bbec
Notes: github-actions[bot] 2025-06-11 14:26:45 +00:00
4 changed files with 22 additions and 8 deletions

View file

@ -1414,6 +1414,18 @@ void Document::update_layout(UpdateLayoutReason reason)
paintable()->recompute_selection_states(*range);
}
// Collect elements with content-visibility: auto. This is used in the HTML event loop to avoid traversing the whole tree every time.
Vector<GC::Ref<Painting::PaintableBox>> paintable_boxes_with_auto_content_visibility;
paintable()->for_each_in_subtree_of_type<Painting::PaintableBox>([&](auto& paintable_box) {
if (paintable_box.dom_node()
&& paintable_box.dom_node()->is_element()
&& paintable_box.computed_values().content_visibility() == CSS::ContentVisibility::Auto) {
paintable_boxes_with_auto_content_visibility.append(paintable_box);
}
return TraversalDecision::Continue;
});
paintable()->set_paintable_boxes_with_auto_content_visibility(move(paintable_boxes_with_auto_content_visibility));
m_layout_root->for_each_in_inclusive_subtree([](auto& node) {
node.reset_needs_layout_update();
return TraversalDecision::Continue;