From d2b7d2440fec1b53903df380b8a8168f084ee792 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 6 Jul 2022 00:21:37 +0200 Subject: [PATCH] LibWeb: Cache flex item main sizes to avoid relayout during same cycle This makes twitter.com actually load & render (although not very well.) --- .../Libraries/LibWeb/Layout/FlexFormattingContext.cpp | 11 ++++++++++- Userland/Libraries/LibWeb/Layout/FormattingState.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 755e6e428e..b633690d94 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 ca330caa65..925b69aae2 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; };