Skip to content

perf: Improve @babel/parser - #18176

Merged
nicolo-ribaudo merged 1 commit into
babel:mainfrom
liuxingbaoyu:perf-parser
Sep 9, 2026
Merged

nicolo-ribaudo merged 1 commit into
babel:mainfrom
liuxingbaoyu:perf-parser

Conversation

@liuxingbaoyu

@liuxingbaoyu liuxingbaoyu commented Aug 7, 2026 •

Copy link
Copy Markdown
Member
Q                       A
Fixed Issues? Fixes #1, Fixes #2
Patch: Bug Fix?
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
License MIT

This PR mainly focuses on some type improvements.

PS F:\babel> node benchmark\babel-parser\real-case.mjs
Recommend running with --expose-gc.
babel-parser/real-case.mjs babel-parser-express.ts @ current: 390 ops/sec ±1.17% 1903 runs (2.628ms)
babel-parser/real-case.mjs babel-parser-express.ts @ baseline: 352 ops/sec ±1.48% 1713 runs (2.92ms)
babel-parser/real-case.mjs jquery-3.6.js @ current: 125 ops/sec ±1.07% 620 runs (8.071ms)
babel-parser/real-case.mjs jquery-3.6.js @ baseline: 118 ops/sec ±1.11% 584 runs (8.566ms)
babel-parser/real-case.mjs ts-checker.mjs @ current: 13.71 ops/sec ±1.9% 69 runs (73ms)
babel-parser/real-case.mjs ts-checker.mjs @ baseline: 12.97 ops/sec ±1.91% 65 runs (78ms)
babel-parser/real-case.mjs ts-checker.ts @ current: 9.88 ops/sec ±1.76% 64 runs (102ms)
babel-parser/real-case.mjs ts-checker.ts @ baseline: 9.67 ops/sec ±1.35% 64 runs (104ms)
babel-parser/real-case.mjs ts-parser.mjs @ current: 117 ops/sec ±0.81% 580 runs (8.625ms)
babel-parser/real-case.mjs ts-parser.mjs @ baseline: 110 ops/sec ±0.79% 546 runs (9.166ms)
babel-parser/real-case.mjs ts-parser.ts @ current: 73.49 ops/sec ±0.41% 367 runs (14ms)
babel-parser/real-case.mjs ts-parser.ts @ baseline: 70.95 ops/sec ±0.94% 354 runs (14ms)
babel-parser/real-case.mjs typescript-5.6.2.js @ current: 2.99 ops/sec ±1.15% 64 runs (336ms)
babel-parser/real-case.mjs typescript-5.6.2.js @ baseline: 2.89 ops/sec ±1.23% 64 runs (346ms)

Comment on lines +375 to 386
// TODO: Enable this
checkNamedExport(): void {
// const { specifiers } = node;
// if (specifiers?.length) {
// node.specifiers = specifiers.filter(
// // @ts-expect-error placeholder typings
// node => node.exported.type === "Placeholder",
// );
// }
// super.checkNamedExport(node);
// node.specifiers = specifiers;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Commenting them out won't change the behavior because we didn't pass any parameters when calling the parent class function in the past, so there was no actual check.

@babel-bot

Copy link
Copy Markdown
Collaborator

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/61997

Comment on lines +393 to +394
const attachComment = (this.optionFlags & OptionFlags.AttachComment) > 0;
let comments: N.Comment[] | undefined;

@liuxingbaoyu liuxingbaoyu Aug 7, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the main reason for the performance improvement, now we only create arrays when needed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7405da9832

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +2236 to +2237
this.checkDuplicateExports(node, "default");
if (this.hasPlugin("exportDefaultFrom")) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve placeholder handling for default-export validation

When the placeholders plugin is enabled, default-export validation now bypasses the plugin hook that previously suppressed these checks. For example, with placeholders and exportDefaultFrom, export default from; was previously accepted as exporting an identifier named from, but the inlined ExportDefaultFromAsIdentifier check now rejects it; similarly, templates containing multiple provisional default exports begin throwing duplicate-export errors. Keep these checks behind an overridable hook, as is still done for named exports, to avoid changing placeholder-template parsing in this performance/type-only change.

Useful? React with 👍 / 👎.

@liuxingbaoyu liuxingbaoyu Aug 7, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I investigated.
This resulted in some behavioral changes, but they seem acceptable.

This used to be legal, now it throws an error.

template(`
  export default %%FIRST%%;
  export default %%SECOND%%;
`);

This now throws an error when exportDefaultFrom and placeholders are enabled.
Ideally, the behavior should throw an error as soon as exportDefaultFrom is enabled, and should not be affected by placeholders. The new behavior is better.

export default from;

);
}

parseTypeOnlyExportSpecifier(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I split parseTypeOnlyImportExportSpecifier into two functions, which may result in a slight increase in size, but I feel that two functions are clearer and may be more efficient, so it's acceptable.

UsingDeclarationInAmbientContext: (kind: "using" | "await using") =>
`'${kind}' declarations are not allowed in ambient contexts.`,
} satisfies ParseErrorTemplates;
/* eslint-disable sort-keys */

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wasn't actually working as we intended, it had previously only suppressed reporting throughout the entire file. Now that there's no code violating this rule, it will be treated as an error by ESLint.

@pkg-pr-new

pkg-pr-new Bot commented Aug 7, 2026

Copy link
Copy Markdown

Open in StackBlitz

commit: 7405da9

@nicolo-ribaudo nicolo-ribaudo added the PR: Performance 🏃‍♀️ A type of pull request used for our changelog categories label Sep 9, 2026
@nicolo-ribaudo
nicolo-ribaudo merged commit acc19f9 into babel:main Sep 9, 2026
58 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: Performance 🏃‍♀️ A type of pull request used for our changelog categories

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants