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
parent df0dc32006
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

@ -23,6 +23,7 @@
#include <LibWeb/HighResolutionTime/TimeOrigin.h>
#include <LibWeb/Page/Page.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Painting/ViewportPaintable.h>
#include <LibWeb/Platform/EventLoopPlugin.h>
#include <LibWeb/Platform/Timer.h>
@ -408,11 +409,8 @@ void EventLoop::update_the_rendering()
// 3. For each element element with 'auto' used value of 'content-visibility':
auto* document_element = document->document_element();
if (document_element) {
document_element->for_each_in_inclusive_subtree_of_type<Web::DOM::Element>([&](auto& element) {
auto const& paintable_box = element.paintable_box();
if (!paintable_box || paintable_box->computed_values().content_visibility() != CSS::ContentVisibility::Auto) {
return TraversalDecision::Continue;
}
for (auto& paintable_box : document->paintable()->paintable_boxes_with_auto_content_visibility()) {
auto& element = as<DOM::Element>(*paintable_box->dom_node());
// 1. Let checkForInitialDetermination be true if element's proximity to the viewport is not determined and it is not relevant to the user. Otherwise, let checkForInitialDetermination be false.
bool check_for_initial_determination = element.proximity_to_the_viewport() == Web::DOM::ProximityToTheViewport::NotDetermined && !element.is_relevant_to_the_user();
@ -424,9 +422,7 @@ void EventLoop::update_the_rendering()
if (check_for_initial_determination && element.is_relevant_to_the_user()) {
had_initial_visible_content_visibility_determination = true;
}
return TraversalDecision::Continue;
});
}
}
// 4. If hadInitialVisibleContentVisibilityDetermination is true, then continue.