perf: more css optimizations#21109
Conversation
Replace per-comparison `value.toLowerCase() === "keyword"` with an allocation-free ASCII case-insensitive helper (`equalsLowerCase`) on the parser hot paths (the `!important` flag and the CssParser keyword checks). This is also spec-aligned: CSS matches keywords, at-rule names, and the `!important` flag ASCII case-insensitively.
`buildExportsSourceMap` scanned every generated line for each export (O(exports x lines)), which dominated source-map generation for export-heavy CSS modules (e.g. Tailwind as a module). Resolve each export's line in one pass by matching each line's leading JSON key against the requested export names.
…shing `_escapeIdentifier` ran two regex tests per character and concatenated char-by-char. Classify each ASCII code once via a lookup table and flush safe runs in bulk, so identifiers that need no escaping return unchanged with no allocation. ~11x faster on escape-heavy CSS-module class names (e.g. Tailwind variant selectors); output is byte-for-byte identical.
…x scan `_unescapeIdentifier` appended char-by-char and `gobbleHex` sliced + lowercased a substring per backslash just to test the next char. Scan hex by index (no slice, case-folded inline) and flush safe runs in bulk; use `indexOf` as the fast path and start offset. ~2.5x faster on escape-heavy selectors (e.g. Tailwind `focus\:sr-only`); output is byte-for-byte identical.
The comment callback eagerly computed line/column (two `LocConverter.get` calls + a loc object) for every comment, but only magic-comment error warnings ever read it. Defer it behind a getter on a `Comment` class, matching the existing lazy `Node.loc`. ~16% faster comment parsing on comment-heavy CSS; output unchanged.
🦋 Changeset detectedLatest commit: d46af3f The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
This PR is packaged and the instant preview is available (28fbdce). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@28fbdce
yarn add -D webpack@https://pkg.pr.new/webpack@28fbdce
pnpm add -D webpack@https://pkg.pr.new/webpack@28fbdce |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #21109 +/- ##
===========================================
+ Coverage 39.48% 92.00% +52.52%
===========================================
Files 439 581 +142
Lines 51495 61433 +9938
Branches 14334 16787 +2453
===========================================
+ Hits 20331 56520 +36189
+ Misses 31164 4913 -26251
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Merging this PR will not alter performance
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | benchmark "asset-modules-bytes", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
248.8 KB | 858.9 KB | -71.03% |
| ❌ | Memory | benchmark "many-modules-commonjs", scenario '{"name":"mode-development","mode":"development"}' |
923.1 KB | 1,820 KB | -49.28% |
| ❌ | Memory | benchmark "side-effects-reexport", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
594.7 KB | 878.1 KB | -32.28% |
| ❌ | Memory | benchmark "css-modules", scenario '{"name":"mode-production","mode":"production"}' |
6.6 MB | 8.4 MB | -20.44% |
| ⚡ | Memory | benchmark "asset-modules-inline", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
1,229.4 KB | 216.2 KB | ×5.7 |
| ⚡ | Memory | benchmark "devtool-eval-source-map", scenario '{"name":"mode-production","mode":"production"}' |
8.1 MB | 6.5 MB | +24.54% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing claude/css-parser-optimization-YZg3E (d46af3f) with main (028c549)
Summary
perf
What kind of change does this PR introduce?
perf
Did you add tests for your changes?
Existing
Does this PR introduce a breaking change?
No
If relevant, what needs to be documented once your changes are merged or what have you already documented?
Nothing
Use of AI
Claude