seek-oss / playroom

Design with JSX, powered by your own component library.
MIT License
4.48k stars 182 forks source link

Replace `@babel/standalone` with `sucrase` for JSX compilation #301

Closed askoufis closed 10 months ago

askoufis commented 10 months ago

sucrase is a much faster alternative to babel. It gets its speed by only supporting modern browsers and versions of node, and sacrificing extensibility. It supports JSX out of the box, and runs in the browser, so this was basically a drop-in replacement for @babel/standalone.

Performance

For small playrooms, the difference in execution time of compileJsx is pretty negligible. Both @babel/standalone and sucrase often compile in <10ms. However, in larger playrooms (tested a Braid playroom with ~2300 lines of code), @babel/standalone often takes between 100-200ms to compile, whereas sucrase still compiles in ~10ms. This results in a noticeable difference to input latency and general responsiveness.

It seems like snippet performance (opening the snippet menu and previewing snippets) has improved a bit too.

Playroom URLs in .txt files because they're too long for github and URL shorteners. Try typing quickly on line 328.

NOTE: These profile were taken from the dev server playroom because it was easier than setting up prod source maps. The compilation time difference is probably a bit smaller in prod build, but the difference in responsiveness is still clearly noticeable in the playroom links above.

Chrome performance profiles

Bundle size

@babel/standalone is a chunky dependency. sucrase is comparatively much lighter.

Future

There's some more stuff we can improve on in the short term, such as using custom JSX pragmas to reduce the amount of code being sent to each iframe (will do a followup PR). We could also try using esbuild-wasm, but its API is async only, so it would involve a bit of refactoring. It's also somewhat slower than sucrase, according to the benchmarks in sucrase's README.

Since we don't specify targets in babel-loader, we're compiling down for the oldest browser possible. AFAIK Playroom has never explicitly advertised its supported browser versions. If we moved to sucrase for the webpack loader we could potentially get some build time speedups, at the cost of only supporting relatively modern browser versions.

changeset-bot[bot] commented 10 months ago

🦋 Changeset detected

Latest commit: eadd0f26fe95d3d8ced93986949cb9cdfe37edb6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package | Name | Type | | -------- | ----- | | playroom | Minor |

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