Hacker News new | ask | show | jobs
by TekMol 1710 days ago
Isn't the browser also an extremely fast Javscript bundler?

How many scripts does a site need to make it feel faster when bundled?

When I visit websites that are rendered serverside, they usually feel instant to me. Even when they load a dozen scripts or so.

6 comments

> How many scripts does a site need to make it feel faster when bundled?

It's because people are using these huge frameworks with a lot of bloated code, it's too big, now devs are forced to do tree shaking and what not to trim the fat... front end JS development has become a madhouse of unnecessary complexity, because of node.js as well...

I hope that with the help of DENO that doesn't suffer from all that cargo culting, front-end development can become a healthier ecosystem...

Yes, some apps are complex, but 99% of front-end UI aren't.

I just saw an (internal) presentation where presenter predicted that in a few coming months we will see a lot more RxJS being used in ReactJS projects. Cannot wait to see it included on webpages which would be just fine with zero JS.
What ESBuild offers over plain ESM is:

- fast TypeScript/JSX compile

- bundling shared code to reduce request waterfall/splitting to reduce redundancy

- bundle optimization (tree shaking/dead code elimination; minification is actually faster than not using it)

- a simple plugin system for use cases like other compiled frameworks like Vue or Svelte, or whatever else you might want in a build pipeline

On the downside, it will put all the code into one giant script that has to be downloaded upfront.

While a website that loads scripts per page will only load the scripts that are needed on the current page.

Unless your site is made of 4 files/modules, you simply must bundle. ESM will download the files in series, as each dependency is discovered. Then compression doesn’t work as well as it will be per-file. Then of course you can’t tree-shake dependencies from npm, so good luck downloading the whole of lodash on your client.

In short you lose the advantages of only download what you need pretty quickly.

> good luck downloading the whole of lodash on your client

I never felt the need to use loadash. But even if a site would do that, it does not seem like a big issue. It is 71k. A Twitter profile page is over 5MB. 70 times the size of that loadash library. An appartment page on AirBnB is over 9MB. An Instagram profile page is over 9MB too.

ESBuild does support code splitting, in case you weren’t aware.
I like Snowpack (https://www.snowpack.dev) because it doesn't actually do any bundling, it just makes sure that the files are in the right place to be loaded (it does compile Typescript files). Because the only thing I actually care about during development is that all the inter-package dependencies are resolved. I don't actually need a fat heap of JS that needs to be rebuilt every time I change something.
Yes, that's why ES modules and import maps are a thing. For example Deno uses them, and they're the new default on Rails 7.
> How many scripts does a site need to make it feel faster when bundled?

Depends on what you're building. If you have many nested dependencies, you need to bundle them, and not rely on the browser to resolve them at runtime and do dozens of roundtrips to the server to fetch them.

That contradicts my experience and what I just described. In my experience, sites do feel instant even if they load dozens of scripts.
If your dozens of scripts are top-level (on the html itself) then you can fetch all of them in parallel — so you wait your connection speed roughly twice (roundtripped).

If they’re nested dependencies (where you don’t identify the next necessary js until you have the first one in hand), the dependency won’t start getting fetched until the predecessor is retrieved. So you wait your connection speed multiplied by depth (x2; roundtripped)

The goal of the bundler is to take the second scenario and turn it into the first scenario.

If they are not waterfalling then yeah. But when a depends on b and b depends on c you will be fetching those serially.

The bundler will have those preprocessed and bundled together.

There will definitely be an inflection point, and it's very dependent on many factors: number and size of scripts, how much of the initial content is SSRed, network bandwidth and latency etc.
Browsers are good at caching JavaScript files, so it depends if the scripts are already cached or not.
I thought HTTP 2 fixed the problem of multiple downloads of small files/dependencies?

The creator of Rails talks about it here: https://world.hey.com/dhh/modern-web-apps-without-javascript...

Khan Academy did a great writeup on their experience (including thoughts about HTTP/2) with various strategies for serving JS, such as:

- Single bundle

- No bundles (all separate files)

- Hybrid

https://blog.khanacademy.org/forgo-js-packaging-not-so-fast/

You can use the Network tab of your preferred browser to see the waterfall. HTTP2 did improve a lot, but it can’t magically resolve N-deep transitive imports without additional information. It was originally designed to have that information provided at the server level, but HTTP Push has been dead for a while. There are physical limitations at work, optimizing requests on the wire is still important.
> When I visit websites that are rendered serverside, they usually feel instant to me. Even when they load a dozen scripts or so

Then they'll be faster doing only one request, this is regardless of ssr or spa

Bundling also gives you slatic analysis (typescript and linting), and frees developers from developing in the dark, like keeping track in their brain what component in what script exposes what global.

> Bundling also gives you slatic analysis (typescript and linting),

No it doesn't do that, typescript compiler does the static analysis and whatever linter does the linting, you don't need a bundler for that, a bundler just takes many source files and bundles them into one.