perf(css): skip inline-style allocation for elements without inline styles

The visibility predicate called getInlineStyleProperty -> getOrCreateStyle,
which always allocated a CSSStyleProperties + CSSStyleDeclaration and inserted
into frame._element_styles, even for elements with no style= attribute. Every
semantic-tree / interactiveElements walk checks visibility on every element, so
this was one wasted allocation per element per walk on the agent's hot path.

Only materialize the inline-style object when one already exists (JS-set styles)
or the element actually carries a style= attribute; otherwise return null
without allocating.
This commit is contained in:
Adrià Arrufat
2026-06-30 15:29:43 +02:00
parent 6f453e0949
commit 41cb1bc176

View File

@@ -864,9 +864,13 @@ const CheckVisibilityOptions = struct {
const INLINE_PRIORITY: u64 = std.math.maxInt(u64);
fn getInlineStyleProperty(el: *Element, property_name: String, frame: *Frame) ?*CSSStyleProperty {
const style = el.getOrCreateStyle(frame) catch |err| {
log.err(.browser, "StyleManager getOrCreateStyle", .{ .err = err });
return null;
const style = frame._element_styles.get(el) orelse blk: {
// No JS-set style object and no style attribute -> nothing inline to read.
if (el.getAttributeSafe(comptime .wrap("style")) == null) return null;
break :blk el.getOrCreateStyle(frame) catch |err| {
log.err(.browser, "StyleManager getOrCreateStyle", .{ .err = err });
return null;
};
};
return style.asCSSStyleDeclaration().findProperty(property_name);
}