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

LibWeb: Avoid layout invalidation for some CSS property changes

Use the new CSS::property_affects_layout() helper to figure out if we
actually need to perform a full relayout after recomputing style.

There are three tiers of required invalidation after an element receives
new style: none, repaint only, or full relayout.

This avoids the need to rebuild the layout tree (and perform layout on
it) when trivial properties like "color" etc are changed.
This commit is contained in:
Andreas Kling 2022-03-16 17:48:50 +01:00
parent 275db39c94
commit f1711a562a
3 changed files with 60 additions and 10 deletions

View file

@ -595,17 +595,20 @@ void Document::update_layout()
m_layout_update_timer->stop();
}
static void update_style_recursively(DOM::Node& node)
static bool update_style_recursively(DOM::Node& node)
{
if (is<Element>(node))
static_cast<Element&>(node).recompute_style();
bool needs_relayout = false;
if (is<Element>(node)) {
needs_relayout |= static_cast<Element&>(node).recompute_style() == Element::NeedsRelayout::Yes;
}
node.set_needs_style_update(false);
if (node.child_needs_style_update()) {
if (node.is_element()) {
if (auto* shadow_root = static_cast<DOM::Element&>(node).shadow_root()) {
if (shadow_root->needs_style_update() || shadow_root->child_needs_style_update())
update_style_recursively(*shadow_root);
needs_relayout |= update_style_recursively(*shadow_root);
}
}
node.for_each_child([&](auto& child) {
@ -616,6 +619,7 @@ static void update_style_recursively(DOM::Node& node)
}
node.set_child_needs_style_update(false);
return needs_relayout;
}
void Document::update_style()
@ -624,9 +628,9 @@ void Document::update_style()
return;
if (!needs_style_update() && !child_needs_style_update())
return;
update_style_recursively(*this);
if (update_style_recursively(*this))
invalidate_layout();
m_style_update_timer->stop();
set_needs_layout();
}
void Document::set_link_color(Color color)