diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 755e6e428e1df1..b633690d94f3f2 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -619,7 +619,16 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size( if (has_definite_main_size(child_box)) return specified_main_size_of_child_box(child_box); - return calculate_indefinite_main_size(flex_item); + // NOTE: To avoid repeated layout work, we keep a cache of flex item main sizes on the + // root FormattingState object. It's available through a full layout cycle. + // FIXME: Make sure this cache isn't overly permissive.. + auto& size_cache = m_state.m_root.flex_item_size_cache; + auto it = size_cache.find(&flex_item.box); + if (it != size_cache.end()) + return it->value; + auto main_size = calculate_indefinite_main_size(flex_item); + size_cache.set(&flex_item.box, main_size); + return main_size; }(); // The hypothetical main size is the item’s flex base size clamped according to its used min and max main sizes (and flooring the content box size at zero). diff --git a/Userland/Libraries/LibWeb/Layout/FormattingState.h b/Userland/Libraries/LibWeb/Layout/FormattingState.h index ca330caa651e16..925b69aae2cfb6 100644 --- a/Userland/Libraries/LibWeb/Layout/FormattingState.h +++ b/Userland/Libraries/LibWeb/Layout/FormattingState.h @@ -107,6 +107,8 @@ struct FormattingState { }; HashMap mutable intrinsic_sizes; + HashMap mutable flex_item_size_cache; + FormattingState const* m_parent { nullptr }; FormattingState const& m_root; };