Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from parcel to esbuild #432

Merged
merged 16 commits into from
Jan 15, 2025
Merged

Switch from parcel to esbuild #432

merged 16 commits into from
Jan 15, 2025

Conversation

jlfwong
Copy link
Owner

@jlfwong jlfwong commented Jun 26, 2023

No timeline on this -- was just curious how close to drop-in it would be.

Some things that need addressing before this can land:

  • Updating build scripts for production builds
  • Fix the hot-reloading code
  • Check sourcemaps
  • Check that minification is enabled fully
  • Update the main .html file to do optimization
  • Ensure cache-busting still works properly by file hashes changing
  • Make code splitting work
  • Compare bundle sizes v.s. parcel
  • Fix local installations running off of file:/// URLs

Fixes #295

@coveralls
Copy link

coveralls commented Jun 26, 2023

Coverage Status

coverage: 43.377% (-0.3%) from 43.693%
when pulling 3e92756 on jlfwong/esbuild
into 911feb6 on main.

@jlfwong
Copy link
Owner Author

jlfwong commented Jan 15, 2025

I tried to revive this as an alternative to #492, but ran into problems with code splitting.

Here's the waterfall for loading the chunks created for parcel:

image

And here's the waterfall for loading chunks created by esbuild:

image

Ignore the sizes -- this is esbuild in development v.s. parcel in production. The parcel version is minified & gzipped.

The part that's a dealbreaker for me is that esbuild generates 6 chunks instead of the desired 4, and requires 2 round trips before the main chunk executes (speedscope.js has to wait for the two chunk-***.js files to download and execute). This happens because these files share common dependencies with the intentionally code-split chunks.

An example of where this happens is lib/profile.ts. This file is used both by the main speedscope.js chunk and the import-***.js chunk. In esbuild's implementation, this means that the contents of lib/profile.ts are split out into a separate chunk which gets asynchronously loaded after the main chunk is downloaded and parsed. (See esbuild's documentation on code splitting)

In parcel's implementation, this code is contained in the main chunk and then somehow referenced from inside of the import-***.js chunk without any additional network overhead.

This is a bummer! I could work around the network waterfall by embedding those initial chunk dependencies directly into the page, but I'd still lose out on compression benefits of having all of the main chunk's contents in a single network payload.

It's possible, however, that the benefits of using the esbuild esm target w/ minification outweighs the loss caused by shared compression.

cat speedscope.js | gzip | wc -c
   47065
cat chunk-EK7ODJWE.js | gzip | wc -c
     337
cat chunk-UCDBZYH3.js | gzip | wc -c
    5620

Those add up to less than the size of just compressing the version output by parcel v1. So if I can get the initial chunks to all load as part of the initial load by embedding multiple script tags, then maybe this is still a performance improvement.

@jlfwong
Copy link
Owner Author

jlfwong commented Jan 15, 2025

I resolved most of the above performance problems, but it unfortunately breaks the version of the build which runs purely off of file:/// URLs (which is also how the local version of speedscope made available via npm install speedscope) works.

image

The problem is that <script type="module"> style scripts flat out refuse to load from file:/// URLs (see whatwg/html#8121) The only solutions I can think of are...

  1. Make a build of the app that's specific to this local build configuration which doesn't use code splitting and therefore doesn't need esm as a target
  2. Drop support for the version of speedscope you can download as a zipfile, and make it mandatory to use speedscope via a script which starts a local server.

Of these, I'm leaning towards option 1 at the moment

@jlfwong jlfwong changed the title WIP: switch from parcel to esbuild Switch from parcel to esbuild Jan 15, 2025
@jlfwong jlfwong merged commit 103e441 into main Jan 15, 2025
6 checks passed
@jlfwong jlfwong deleted the jlfwong/esbuild branch January 15, 2025 22:47
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.

Switch from parcel to esbuild
2 participants