LibWeb: Cache parsed selectors for querySelectorAll/querySelector

Add a per-Document cache that maps selector strings to their parsed
SelectorList results. This avoids re-tokenizing and re-parsing the
same selector strings on every call, which is a huge win for pages
that repeatedly call querySelectorAll with the same selectors.

On microsoft.com, where they spam querySelectorAll with the same two
selectors, profiling showed 62% of main thread time was spent
re-parsing selectors. This cache eliminates that entirely for
repeated queries.
This commit is contained in:
Andreas Kling
2026-03-20 14:56:12 -05:00
committed by Andreas Kling
parent d8fc4e9ee2
commit 194f17928f
Notes: github-actions[bot] 2026-03-20 23:33:24 +00:00
3 changed files with 53 additions and 10 deletions

View File

@@ -8115,4 +8115,20 @@ void Document::exit_pointer_lock()
dbgln("FIXME: exit_pointer_lock()");
}
Optional<CSS::SelectorList> const* Document::cached_query_selector_result(String const& selector_text) const
{
auto it = m_selector_query_cache.find(selector_text);
if (it == m_selector_query_cache.end())
return nullptr;
return &it->value;
}
void Document::cache_query_selector_result(String selector_text, Optional<CSS::SelectorList> result)
{
if (m_selector_query_cache.size() >= max_selector_query_cache_size)
m_selector_query_cache.remove(m_selector_query_cache.begin());
m_selector_query_cache.set(move(selector_text), move(result));
}
}