Skip to content

perf: avoid babel in dev by using magic string for hook names injection#183

Merged
JoviDeCroock merged 1 commit intopreactjs:mainfrom
sapphi-red:perf/avoid-babel-in-dev-by-using-magic-string-for-hook-names-injection
Feb 18, 2026
Merged

perf: avoid babel in dev by using magic string for hook names injection#183
JoviDeCroock merged 1 commit intopreactjs:mainfrom
sapphi-red:perf/avoid-babel-in-dev-by-using-magic-string-for-hook-names-injection

Conversation

@sapphi-red
Copy link
Contributor

This PR adds transformHookNamesPlugin which is a port of babel-plugin-transform-hook-names and uses magic-string to update the code instead of babel. With this change, babel no longer has to be run unless it's specified by the option. This improves performance by up to 31%.

Benchmark

I tested this change with a benchmark script at sapphi-red@2ff89c2.

2000 Components without any hook calls

npm run benchmark:load -- --files 2000 --children 5 --runs 5 --warmups 1

  • Without this PR: 3071.20ms
  • With this PR: 2110.64ms (-960.56ms, -31.28%)

2000 Components with useState calls

npm run benchmark:load -- --files 2000 --children 5 --runs 5 --warmups 1 --use-state

  • Without this PR: 3515.42ms
  • With this PR: 2641.48ms (-873.94ms, -24.87%)

]
: []),
jsxPlugin,
...(!useBabel
Copy link
Member

Choose a reason for hiding this comment

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

Prefresh of line 300 will still be using Babel though 😅

Copy link
Contributor Author

@sapphi-red sapphi-red Feb 17, 2026

Choose a reason for hiding this comment

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

Yes, it is. I meant the babel transform written directly in this plugin. The prefresh plugin currently runs a separate babel transform (parse + transform + codegen) pass, so this PR will remove half of the babel tranform pass.

In Vite 8, the react refresh transform can be handled by Oxc. So if we use that feature and port https://github.com/swc-project/plugins/tree/main/packages/prefresh and use magic-string for it similarly, we can remove babel completely.

Copy link
Member

Choose a reason for hiding this comment

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

If you need any help with prefresh LMK, I'm actively working on the babel plugin for signals support atm

@JoviDeCroock JoviDeCroock merged commit d2d5681 into preactjs:main Feb 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants