Hacker News new | ask | show | jobs
by constexpr 2310 days ago
It's cool to wake up in the morning and see my project on HN! For the record, I'm not trying to compete with the entire JavaScript ecosystem and create an extremely flexible build system that can build anything.

I'm trying to create a build tool that a) works well for a given sweet spot of use cases (bundling JavaScript, TypeScript, and maybe CSS) and b) resets the expectations of the community for what it means for a JavaScript build tool to be fast. Our current tools are way to slow in my opinion. Let's build faster tools!

6 comments

This is a cool project and I like your point about resetting expectations wrt performance. I work in an all-Python shop and it’s maddening that people are relatively okay with builds (mostly installing dependencies) in the tens of minutes, CLIs that take ten seconds to print —help, and requests that take tens of seconds at the median and timeout at p95, not to mention at least 5x more spend on our cloud bill.

With something like Go, it would take us a little up front effort to learn the language and we would easily get a 1-2 order of magnitude improvement in most of these metrics (and any productivity difference is well within the margin for error). This is our shop, but it’s also a microcosm of the broader Python community (e.g., takes half an hour to resolve dependencies for medium sized projects). It would be really cool if the broader community would rally around PyPy and improve its support or if CPython would move be willing to concede some backwards compatibility on its extensions interface in order to allow for more optimizations.

constexpr - Cool project!

For those of us with slow internet connections please change your Makefile to use a shallow clone:

``` github/three: mkdir -p github git clone --depth 1 https://github.com/mrdoob/three.js.git github/three -b r108 cd github/three && git checkout r108 ```

This would save a couple of gigs and hours in download.

Just skimming your code I see variable mangling but no AST optimizations, is that correct? Which is odd because you show similar output sizes to the JS bundlers.

Thanks! Will do. No wonder the three.js repo takes so long to download :)

You probably aren't seeing the AST optimizations because they are actually in the parser. Search for "mangleSyntax" to find the optimization code.

This would normally be done in a separate pass but I'm trying to minimize the number of passes done over the full AST for speed. I figured it'd be faster to optimize the AST as it's parsed because the newly-created AST nodes are likely to still be in the CPU cache. That said, I haven't tested the performance impact of doing this. I just did this based on intuitions from performance work on previous compiler projects.

Thanks - I never thought to look in the parser for AST optimization.

By the way, it doesn't affect timings by more than 20%, but that repo has locked in rather old versions of rollup, terser, and other packages. You can disable tree shaking in rollup with --no-treeshake and still get comparable bundle sizes after using terser. That would save 3 seconds. There's no tree shaking opportunity in re-exporting all the symbols from the same library 10 times - all code must be retained. Using terser({compress: false}) would save an additional 17 seconds at the expense of making the final bundle 3% larger - 6.01mb total. Mind you even with upgraded packages and these config tweaks rollup+terser would still be 30x slower than esbuild - compiled languages will always win in speed.

Bundling and minifying a real app rather than a library might yield more interesting bundle size numbers due to dead code elimination. Providing gzip sizes would be interesting too - they aren't always proportional to the original ungzipped sizes.

Yeah benchmarks are tricky. I'd rather not tweak the parameters for Rollup in this case because then it wouldn't be a fair comparison. Rollup would then be cheating because it has to do less work.

It could definitely be useful to have additional benchmarks that test other configurations though. For example, development build speed is also relevant and would make a good benchmark. I'll think about adding more benchmarks if I have time.

I also want a benchmark that tests a real app. I just haven't yet found a large-enough open source app to use as a benchmark. Do you know of one? I work at Figma and Figma's main app makes a great test case, but obviously using that as benchmark wouldn't be reproducible by others outside of Figma. Figma's code base is around the same size as the benchmark I'm using (so 10x the size of three.js).

Ultimately I'm planning on implementing a TypeScript parser in esbuild, at which point I'd like to switch to a benchmark of a TypeScript code base. I also want to include multiple entry points in the benchmark because that's something Figma's main app uses, and esbuild has specific optimizations for that case.

Long story short the benchmark I'm currently using was helpful for me during the initial development but it's not the final one I plan to use, and I will likely completely change it as the project evolves.

Edit: Oh yeah and gzip sizes are great to track. I've tracked these for previous compiler projects I've done and you're right, sometimes you need to make the output larger to make the gzip output smaller. I haven't looked at the gzip sizes at all yet and there is room for improvement. Check out https://github.com/evanw/esbuild/issues/6#issuecomment-58667... for an idea of what specific numbers might currently look like for esbuild compared to other minifiers.

Fair enough you'd want a like-for-like comparison. Even without changing the default configuration, upgrading the JS packages would improve their speed somewhat.

Unfortunately I am not aware of a large public ES codebase to test against. Most projects use Typescript as you mentioned. You could grab the ES bundle made by several projects and test against that, but that also wouldn't be a fair comparison.

The results in https://user-images.githubusercontent.com/406394/74600139-d1... are very informative. It matches my expectations.

I've been studying the Go code in esbuild - very clean and extensible. I think this project has a lot of potential. Thanks for sharing it with the world.

--depth 1 should be known by more people. I have seen many people cloning entire repos or downloading entire .zip file from GitHub.
Since it already has JSX support, adding CSS will cater for 80% of use cases.
Very cool project, do you know how this compares with Hugo's javascript minifier / bundler?
Hugo uses https://github.com/tdewolff/minify internally, so that’s the relevant comparison.
This supports ES6 modules, which I believe are totally unsupported by Hugo Pipes. I remember being annoyed at having to throw node and webpack into the pipeline just because of that (which slowed everything to a crawl).
Hugo doesn't have a JavaScript bundler, it just lets you concatenate JavaScript files which is different from a JS bundler which needs to support JS modules.
I’d like to know this as well.
Awesome! Is this used anywhere in production?
The readme says no.
Thank you for making it!