From 94d8f90a96748afc0ce964bbed5ff6ce5a49f71d Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Thu, 19 Mar 2026 08:44:21 +0800 Subject: [PATCH 1/3] Bucket stylesheet rules In the first iteration of this, we kept an ArrayList of all rules with visibility properties. Why bother evaluating if a rule's selector matches an element if that rule doesn't have any meanignful (i.e. visibility) properties? This commit enhances that approach by bucketing the rules. Given the following selectors: .hidden {....} .footer > .small {...} We can store the rules based on their right-most selector. So, given an element we can do: if (getId(el)) |id| { const rules = id_lookup.get(id) orelse continue; // check rules } if (getClasses(el)) |classes| { for (classes) |c| { const rules = class_lookup(c) orelse continue; // chck rules } } ... On an amazon product page, the total list of visibility-related rules was ~230. Now, scanning 230 rules for a match isn't _aweful_, but remember that this has to be done up the ancestor tree AND, for Amazon, this is called over 20K times. This change requires that the StyleManager becomes more matching/parsing-aware but a typical visibility check on that same Amazon product page only has to check 2 rules (down from 230) and often has to check 0 rules. Also, we now filter out a few more interactive-related pseudo-elements, e.g. :hover. These aren't supported by the browser as a whole (i.e. they can _never_ match), so they can be filtered out early, when building the rules lookup. --- src/browser/StyleManager.zig | 299 ++++++++++++++++++++++++++++++----- 1 file changed, 263 insertions(+), 36 deletions(-) diff --git a/src/browser/StyleManager.zig b/src/browser/StyleManager.zig index 211e4fed..57fea65d 100644 --- a/src/browser/StyleManager.zig +++ b/src/browser/StyleManager.zig @@ -41,14 +41,24 @@ pub const VisibilityCache = std.AutoHashMapUnmanaged(*Element, bool); pub const PointerEventsCache = std.AutoHashMapUnmanaged(*Element, bool); // Tracks visibility-relevant CSS rules from