diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index f2c498ed4db..7abccaa1fb6 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -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> paintable_boxes_with_auto_content_visibility; + paintable()->for_each_in_subtree_of_type([&](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; diff --git a/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp b/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp index 0306b963282..6b5d0f72ee0 100644 --- a/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp +++ b/Libraries/LibWeb/HTML/EventLoop/EventLoop.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -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([&](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(*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. diff --git a/Libraries/LibWeb/Painting/ViewportPaintable.cpp b/Libraries/LibWeb/Painting/ViewportPaintable.cpp index e80f344bca4..30602b45f0d 100644 --- a/Libraries/LibWeb/Painting/ViewportPaintable.cpp +++ b/Libraries/LibWeb/Painting/ViewportPaintable.cpp @@ -395,6 +395,7 @@ void ViewportPaintable::visit_edges(Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(clip_state); + visitor.visit(m_paintable_boxes_with_auto_content_visibility); } } diff --git a/Libraries/LibWeb/Painting/ViewportPaintable.h b/Libraries/LibWeb/Painting/ViewportPaintable.h index 4e569c365db..424f8edff24 100644 --- a/Libraries/LibWeb/Painting/ViewportPaintable.h +++ b/Libraries/LibWeb/Painting/ViewportPaintable.h @@ -40,6 +40,9 @@ public: ScrollState const& scroll_state() const { return m_scroll_state; } + void set_paintable_boxes_with_auto_content_visibility(Vector> paintable_boxes) { m_paintable_boxes_with_auto_content_visibility = move(paintable_boxes); } + ReadonlySpan> paintable_boxes_with_auto_content_visibility() const { return m_paintable_boxes_with_auto_content_visibility; } + private: void build_stacking_context_tree(); @@ -49,6 +52,8 @@ private: ScrollState m_scroll_state; bool m_needs_to_refresh_scroll_state { true }; + + Vector> m_paintable_boxes_with_auto_content_visibility; }; }