LibWeb: Re-evaluate media queries only when things they depend on change

Before this change we were re-evaluating media queries on every frame
which adds up in 1-4% in profiles on Discord.
This commit is contained in:
Aliaksandr Kalenik 2025-08-05 16:56:05 +02:00 committed by Jelle Raaijmakers
parent 3920194bca
commit 7a34bc2700
Notes: github-actions[bot] 2025-08-05 15:26:02 +00:00
4 changed files with 17 additions and 3 deletions

View file

@ -3412,12 +3412,17 @@ void Document::run_the_scroll_steps()
void Document::add_media_query_list(GC::Ref<CSS::MediaQueryList> media_query_list)
{
m_needs_media_query_evaluation = true;
m_media_query_lists.append(*media_query_list);
}
// https://drafts.csswg.org/cssom-view/#evaluate-media-queries-and-report-changes
void Document::evaluate_media_queries_and_report_changes()
{
if (!m_needs_media_query_evaluation)
return;
m_needs_media_query_evaluation = false;
// NOTE: Not in the spec, but we take this opportunity to prune null WeakPtrs.
m_media_query_lists.remove_all_matching([](auto& it) {
return it.is_null();

View file

@ -540,6 +540,7 @@ public:
void run_the_scroll_steps();
void evaluate_media_queries_and_report_changes();
void set_needs_media_query_evaluation() { m_needs_media_query_evaluation = true; }
void add_media_query_list(GC::Ref<CSS::MediaQueryList>);
GC::Ref<CSS::VisualViewport> visual_viewport();
@ -1073,6 +1074,7 @@ private:
Vector<GC::Ref<EventTarget>> m_pending_scrollend_event_targets;
// Used by evaluate_media_queries_and_report_changes().
bool m_needs_media_query_evaluation { false };
Vector<WeakPtr<CSS::MediaQueryList>> m_media_query_lists;
bool m_needs_full_style_update { false };

View file

@ -2370,6 +2370,7 @@ void Navigable::set_viewport_size(CSSPixelSize size)
if (auto document = active_document()) {
// NOTE: Resizing the viewport changes the reference value for viewport-relative CSS lengths.
document->invalidate_style(DOM::StyleInvalidationReason::NavigableSetViewportSize);
document->set_needs_media_query_evaluation();
if (auto layout_node = document->layout_node())
layout_node->set_needs_layout_update(DOM::SetNeedsLayoutReason::NavigableSetViewportSize);
}

View file

@ -145,22 +145,28 @@ void PageClient::set_palette_impl(Gfx::PaletteImpl& impl)
void PageClient::set_preferred_color_scheme(Web::CSS::PreferredColorScheme color_scheme)
{
m_preferred_color_scheme = color_scheme;
if (auto* document = page().top_level_browsing_context().active_document())
if (auto* document = page().top_level_browsing_context().active_document()) {
document->invalidate_style(Web::DOM::StyleInvalidationReason::SettingsChange);
document->set_needs_media_query_evaluation();
}
}
void PageClient::set_preferred_contrast(Web::CSS::PreferredContrast contrast)
{
m_preferred_contrast = contrast;
if (auto* document = page().top_level_browsing_context().active_document())
if (auto* document = page().top_level_browsing_context().active_document()) {
document->invalidate_style(Web::DOM::StyleInvalidationReason::SettingsChange);
document->set_needs_media_query_evaluation();
}
}
void PageClient::set_preferred_motion(Web::CSS::PreferredMotion motion)
{
m_preferred_motion = motion;
if (auto* document = page().top_level_browsing_context().active_document())
if (auto* document = page().top_level_browsing_context().active_document()) {
document->invalidate_style(Web::DOM::StyleInvalidationReason::SettingsChange);
document->set_needs_media_query_evaluation();
}
}
void PageClient::set_is_scripting_enabled(bool is_scripting_enabled)