Skip to content

Commit 2b8883c

Browse files
committed
css: improve lexer identifier parsing performance
1 parent f6f8b27 commit 2b8883c

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

internal/css_lexer/css_lexer.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -610,12 +610,24 @@ func (lexer *lexer) wouldStartNumber() bool {
610610
return false
611611
}
612612

613+
// Note: This function is hot in profiles
613614
func (lexer *lexer) consumeName() string {
614-
// Common case: no escapes, identifier is a substring of the input
615-
for IsNameContinue(lexer.codePoint) {
615+
// Common case: no escapes, identifier is a substring of the input. Doing this
616+
// in a tight loop that avoids UTF-8 decoding and that increments a single
617+
// number instead of doing "step()" is noticeably faster. For example, doing
618+
// this sped up end-to-end parsing and printing of a large CSS file from 97ms
619+
// to 84ms (around 15% faster).
620+
contents := lexer.source.Contents
621+
if IsNameContinue(lexer.codePoint) {
622+
n := len(contents)
623+
i := lexer.current
624+
for i < n && IsNameContinue(rune(contents[i])) {
625+
i++
626+
}
627+
lexer.current = i
616628
lexer.step()
617629
}
618-
raw := lexer.source.Contents[lexer.Token.Range.Loc.Start:lexer.Token.Range.End()]
630+
raw := contents[lexer.Token.Range.Loc.Start:lexer.Token.Range.End()]
619631
if !lexer.isValidEscape() {
620632
return raw
621633
}

0 commit comments

Comments
 (0)