From 3b7149575734069bb7e2bd6f7e9164fe6fdf36ff Mon Sep 17 00:00:00 2001 From: jvoisin Date: Wed, 27 May 2026 15:26:22 +0200 Subject: [PATCH] perf: pre-check raw class attribute in HasClass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HasClass normalized every matching element's class attribute with classTrimReplacer before checking for the target token, even when the raw attribute value could not possibly contain that class at all. Add a cheap strings.Contains(attr.Val, rawClass) pre-check and only run the replacer on plausible matches. This preserves behavior for class attributes containing tabs/newlines while skipping most of the work on misses. BenchmarkHasClass on arm64 over 10 runs: name old time/op new time/op delta HasClass-8 9.809µs 2.660µs -72.89% (p=0.000) --- property.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/property.go b/property.go index beabc5d..ac8e471 100644 --- a/property.go +++ b/property.go @@ -137,12 +137,16 @@ func (s *Selection) AddClass(class ...string) *Selection { // HasClass determines whether any of the matched elements are assigned the // given class. func (s *Selection) HasClass(class string) bool { + rawClass := class class = " " + class + " " for _, n := range s.Nodes { if n.Type != html.ElementNode { continue } if attr := getAttributePtr("class", n); attr != nil { + if !strings.Contains(attr.Val, rawClass) { + continue + } val := classTrimReplacer.Replace(attr.Val) if strings.Contains(" "+val+" ", class) { return true