LibWeb: Skip :has() invalidation in update_style when nothing is pending
Add a document-level boolean flag that tracks whether any :has() invalidations have been scheduled. This avoids iterating over all shadow roots just to check is_empty() on each style scope when no :has() invalidations are pending, which is the common case during scrolling on complex pages like Reddit. Results in ~10% reduction of is_empty() calls in profiles when scrolling on Reddit.
This commit is contained in:
parent
38e53b5600
commit
eea9837438
4 changed files with 17 additions and 5 deletions
|
|
@ -468,6 +468,12 @@ void StyleScope::for_each_active_css_style_sheet(Function<void(CSS::CSSStyleShee
|
|||
}
|
||||
}
|
||||
|
||||
void StyleScope::schedule_ancestors_style_invalidation_due_to_presence_of_has(DOM::Node& node)
|
||||
{
|
||||
m_pending_nodes_for_style_invalidation_due_to_presence_of_has.set(node);
|
||||
document().set_needs_invalidation_of_elements_affected_by_has();
|
||||
}
|
||||
|
||||
void StyleScope::invalidate_style_of_elements_affected_by_has()
|
||||
{
|
||||
if (m_pending_nodes_for_style_invalidation_due_to_presence_of_has.is_empty()) {
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ public:
|
|||
|
||||
void invalidate_style_of_elements_affected_by_has();
|
||||
|
||||
void schedule_ancestors_style_invalidation_due_to_presence_of_has(DOM::Node& node) { m_pending_nodes_for_style_invalidation_due_to_presence_of_has.set(node); }
|
||||
void schedule_ancestors_style_invalidation_due_to_presence_of_has(DOM::Node& node);
|
||||
|
||||
void visit_edges(GC::Cell::Visitor&);
|
||||
|
||||
|
|
|
|||
|
|
@ -1690,10 +1690,13 @@ void Document::update_style()
|
|||
// style change event. [CSS-Transitions-2]
|
||||
m_transition_generation++;
|
||||
|
||||
style_scope().invalidate_style_of_elements_affected_by_has();
|
||||
for_each_shadow_root([&](auto& shadow_root) {
|
||||
shadow_root.style_scope().invalidate_style_of_elements_affected_by_has();
|
||||
});
|
||||
if (m_needs_invalidation_of_elements_affected_by_has) {
|
||||
m_needs_invalidation_of_elements_affected_by_has = false;
|
||||
style_scope().invalidate_style_of_elements_affected_by_has();
|
||||
for_each_shadow_root([&](auto& shadow_root) {
|
||||
shadow_root.style_scope().invalidate_style_of_elements_affected_by_has();
|
||||
});
|
||||
}
|
||||
|
||||
if (!m_style_invalidator->has_pending_invalidations() && !needs_full_style_update() && !needs_style_update() && !child_needs_style_update())
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -813,6 +813,8 @@ public:
|
|||
void set_needs_to_resolve_paint_only_properties() { m_needs_to_resolve_paint_only_properties = true; }
|
||||
void set_needs_animated_style_update() { m_needs_animated_style_update = true; }
|
||||
|
||||
void set_needs_invalidation_of_elements_affected_by_has() { m_needs_invalidation_of_elements_affected_by_has = true; }
|
||||
|
||||
void set_needs_accumulated_visual_contexts_update(bool value) { m_needs_accumulated_visual_contexts_update = value; }
|
||||
bool needs_accumulated_visual_contexts_update() const { return m_needs_accumulated_visual_contexts_update; }
|
||||
|
||||
|
|
@ -1308,6 +1310,7 @@ private:
|
|||
|
||||
bool m_needs_to_resolve_paint_only_properties { true };
|
||||
bool m_needs_accumulated_visual_contexts_update { false };
|
||||
bool m_needs_invalidation_of_elements_affected_by_has { false };
|
||||
|
||||
mutable GC::Ptr<WebIDL::ObservableArray> m_adopted_style_sheets;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue