Ver código fonte

LibWeb: Avoid some unnecessary inside layouts during intrinsic sizing

When calculating intrinsic sizes, we don't need to recurse into *every*
box and layout its insides. IIUC, we can skip any unconstrained box with
definite sizes in both axes. So this patch does exactly that.
Andreas Kling 3 anos atrás
pai
commit
83bb16ede3

+ 14 - 0
Userland/Libraries/LibWeb/Layout/FormattingContext.cpp

@@ -146,6 +146,20 @@ OwnPtr<FormattingContext> FormattingContext::create_independent_formatting_conte
 
 OwnPtr<FormattingContext> FormattingContext::layout_inside(Box const& child_box, LayoutMode layout_mode)
 {
+    {
+        // OPTIMIZATION: If we're doing intrinsic sizing and `child_box` has definite size in both axes,
+        //               we don't need to layout its insides. The size is resolvable without learning
+        //               the metrics of whatever's inside the box.
+        auto const& used_values = m_state.get(child_box);
+        if (layout_mode == LayoutMode::IntrinsicSizing
+            && used_values.width_constraint == SizeConstraint::None
+            && used_values.height_constraint == SizeConstraint::None
+            && used_values.has_definite_width()
+            && used_values.has_definite_height()) {
+            return nullptr;
+        }
+    }
+
     if (!child_box.can_have_children())
         return {};
 

+ 2 - 1
Userland/Libraries/LibWeb/Layout/InlineFormattingContext.cpp

@@ -150,7 +150,8 @@ void InlineFormattingContext::dimension_box_on_line(Box const& box, LayoutMode l
             box_state.set_content_height(height_value.resolved(box, container_height).to_px(inline_block));
         }
 
-        independent_formatting_context->parent_context_did_dimension_child_root_box();
+        if (independent_formatting_context)
+            independent_formatting_context->parent_context_did_dimension_child_root_box();
         return;
     }