← Back to context

Comment by jakub_g

9 days ago

To me, the main problem is that inevitably, any SPA with dozens of contributors will grow into a multi-megabyte-bundle mess.

Preventing it it's extremely hard, because the typical way of developing code is to write a ton of code, add a ton of dependencies, and let the bundler figure it out.

Visualizing the entire codebase in terms of "what imports what" is impossible with tens of thousands of files.

Even when you do splitting via async `import()`, all you need is one PR that imports something in a bad way and it bloats the bundle by hundreds of kilobytes or megabytes, because something that was magically outsourced to an async bundle via the bundler suddenly becomes mandatory in the main bundle via a static import crossing the boundary.

The OP mentions it here:

> It’s often much easier to add things on a top-level component’s context and reuse them throughout the app, than it is to add them only where needed. But doing this means you’re paying the cost before (and whether) you need it.

> It’s much simpler to add something as a synchronous top-level import and force it to be present on every code path, than it is to load it conditionally and deal with the resulting asynchronicity.

> Setting up a bundler to produce one monolithic bundle is trivial, whereas splitting things up per route with shared bundles for the common bits often involves understanding and writing some complex configuration.

You can prevent that by having strong mandatory budgets on every PR, which checks that the bundle size did not grow by more than X kB.

But even then, the accumulation of 100s/1000s of PRs each adding 1KB, bloats the bundle enough to become noticeable eventually.

Perf work is thankless work, and having one perf team trying to keep things at bay while there are dozens of teams shipping features at a fast pace is not gonna cut it.

It makes sense to have separate entry points for landing pages, no need for fancy providers and heavy imports.

In practice people are more than willing to wait for an SPA to load if it works well (figma, gmail/gdocs, discord's browser version used to be pretty good too, and then of course there are the horrible counter-examples AWS/GCP control panels, and so on).

Exactly. To avoid dependency explosion, you need at least one of 1) most libraries built internally 2) great discipline across teams 3) significant performance investment/mandate/enforcement (which likely comes from business requirement eg page load time). I have rarely seen that in my limited experience.