perf(parser): shave instruction off parse_jsx_element_name (#26355)

Micro-optimization to `parse_jsx_element_name`.

`parse_jsx_element_name` inspects the first byte of the identifier name to determine if it should be treated as a reference (`<Foo>` vs `<div>`).

`parse_jsx_identifier` already ensured the identifier is valid, so that first byte can only be one of `[A-Za-z$_]` or the identifier starts with a non-ASCII character. Utilize this constraint to make the "is this a reference" check cheaper.

The new version compiles down to a single `cmp` instruction, shaving off one instruction from the previous version.

It's only 1 instruction, but why not?
This commit is contained in:
overlookmotel committed 2026-09-05 19:15:10 +00:00
1 parent 9780663c17
commit a5be474fcf
1 file changed
+10 -5
+10 -5
View File
@@ -170,14 +170,19 @@ impl<'a, C: Config> ParserImpl<'a, C> {
// In case of a fatal error in `parse_jsx_identifier`, `name` is an empty string,
// so `!contains_dash` check must be first to avoid a panic in `name.as_bytes()[0]`.
//
// The identifier has already been validated by the parser, so for ASCII characters
// we know it can only be `a-z`, `A-Z`, `_` or `$`.
// Use a fast path for ASCII to avoid expensive Unicode operations in the common case.
// The identifier has already been validated by `parse_jsx_identifier`,
// so for ASCII characters we know it can only be `a-z`, `A-Z`, `_` or `$`.
// The 3-arm match below compiles down to a single `cmp` instruction.
// https://godbolt.org/z/jq3Gd7YrP
let name = identifier.name.as_str();
let is_reference = !contains_dash // Exclude hyphenated custom elements
&& match name.as_bytes()[0] {
b if b.is_ascii() => !b.is_ascii_lowercase(), // Matches A-Z, _, $
_ => true, // Non-ASCII characters are always treated as references
// Non-ASCII characters are always treated as references
b if !b.is_ascii() => true,
// Matches A-Z, _, $
b if b < b'a' => true,
// Matches a-z
_ => false
};
if is_reference {