Browse Source

LibWeb: Don't relayout when visibility changes between visible/hidden

Layout will be identical for both of those values, so only a repaint is
necessary. If it changes to/from "collapse" however, we do need to
relayout. This means we can't simply use the "affects-layout" mechanism.
We have to write a little bit of custom code.

This makes Google Groups (and surely many other sites) significantly
more responsive by avoiding large amounts of layout work.
Andreas Kling 2 years ago
parent
commit
f37f081f15
1 changed files with 10 additions and 1 deletions
  1. 10 1
      Userland/Libraries/LibWeb/DOM/Element.cpp

+ 10 - 1
Userland/Libraries/LibWeb/DOM/Element.cpp

@@ -415,8 +415,17 @@ static RequiredInvalidation compute_required_invalidation(CSS::StyleProperties c
             return RequiredInvalidation::Relayout;
             return RequiredInvalidation::Relayout;
         if (*old_value == *new_value)
         if (*old_value == *new_value)
             continue;
             continue;
-        if (CSS::property_affects_layout(property_id))
+
+        // OPTIMIZATION: Special handling for CSS `visibility`:
+        if (property_id == CSS::PropertyID::Visibility) {
+            // We don't need to relayout if the visibility changes from visible to hidden or vice versa. Only collapse requires relayout.
+            if ((old_value->to_identifier() == CSS::ValueID::Collapse) != (new_value->to_identifier() == CSS::ValueID::Collapse))
+                return RequiredInvalidation::Relayout;
+            // Of course, we still have to repaint on any visibility change.
+            requires_repaint = true;
+        } else if (CSS::property_affects_layout(property_id)) {
             return RequiredInvalidation::Relayout;
             return RequiredInvalidation::Relayout;
+        }
         if (CSS::property_affects_stacking_context(property_id))
         if (CSS::property_affects_stacking_context(property_id))
             requires_stacking_context_tree_rebuild = true;
             requires_stacking_context_tree_rebuild = true;
         requires_repaint = true;
         requires_repaint = true;