Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

ES Modules are great. Building JS applications is so much speedier, leaner and more fun now that they are supported widely.

One fallacy the author falls for is that they think one needs a build step "anyway" because otherwise there would be too many requests to the backend.

Loading an AirBnB listing causes 250 requests and loads 10MB of data.

With a leaner approach, using ES Modules, the same functionality can be done with a fraction of those requests. And then - because not bundled - all the modules that will be used on another page will be cached already.

I use ES Modules for all my front end development and I get nothing but praise for how snappy my web applications are compared to the competition.



Any moderately complex frontend application already has to have some sort of build system. One common example is using TypeScript (and these days I don't see the point of using JavaScript and spending hours to fix bugs generated by its missing type safety), or using JSX syntax that must be transpiled, or even if you use plain JS, to transpile it to support older browsers (yes, there is still too much people using Internet Explorer to ignore it).

If you already have a build system, the most sensible thing to me is letting the build system do their stuff and not worry about it. When I write a web application in React with TypeScript (the setup that I usually use) I don't worry about dependencies, and I use the ES modules import syntax (that is better than the CommonJS one) that gets transpiled to CommonJS without I even notice. So why bother changing that? It works, it produces a minified and optimized single .js file that is easy to serve from a webserver, I don't see points against it.


> Loading an AirBnB listing causes 250 requests and loads 10MB of data.

How many of these requests are dependent? Lazily loading hundreds of images doesn't impact page responsiveness, but loading an import of an import of an import before your page does anything is unacceptable.

> I use ES Modules for all my front end development and I get nothing but praise for how snappy my web applications are compared to the competition.

So you actually ship unbundled ES modules? How much code is that? I dare you to bundle it up (rollup/esbuild) and tell me that doesn't improve load times. Comparing to the average website overloaded with crap is a very low bar.


    tell me that doesn't improve load times
It will negatively impact load times.

Either you only bundle what is needed on the current page. Then the next page will load slower because it needs to bundle all those modules again as it uses a slightly different set of modules.

Or you bundle everything used on any page your users might go to during their session. This will give you a giant blob that has to be loaded upfront which contains a ton of modules the user never need during their browsing session.


That's true if you create your own bundle yourself. Famous frameworks like Next.js or Nuxt make much smarter bundles, with common dependencies grouped together, and bundling the rest by page/view, then loading each bundle when needed.


It’s still a tradeoff, though. Let’s say a website has three pages: /a, /b and /c. Two of those pages, /a and /b, each use the module `foo`. Where should `foo` get bundled? If you put it in the “common” bundle, it’ll get served to /c even though it’s not needed. If you put it in both of the bundles for /a and /b, the client will download it twice.


Most bundlers:

- have more sophisticated dependency tracking and will split a separate chunk for a/b

- can produce some kind of a manifest to allow you to preload and avoid nested waterfalls

- provide some mechanism for greater control over what gets chunked separately or combined, for the usage/caching scenarios you’ll undoubtedly know better than a general purpose program


You don’t have to have a single bundle or just main one and common one. Split into as many as you (or a bundler) see fit. In the worst degenerate case you’ll end up with every module bundled separately and preloaded on every page, just like ESM, but without deferred roundtrips for nested dependencies.


>And then - because not bundled - all the modules that will be used on another page will be cached already.

Why isn't anyone else mentioning this feature? I'm not a browser developer but this seems like a clear win, and indeed makes bundling unnecessary. I'm assuming that it's shared between domains, too - or are people's dependencies so fragmented that there's basically no sharing between domains?


I believe sharing cached code between domains has been almost entirely eliminated by browsers now, because it turned out to be a huge privacy leak: a malicious domain could attempt to load code that was used by another domain, time how long it took to load and use that to determine if the user had visited that other site.

Browsers fixed this by making the browser cache no longer shared between domains.


Hm, I wonder if this could be circumvented by doing timing attacks against the CDN cache? That's still shared between domains...



That's the cache in the browser, not the cache in the CDN.


Oh, I see what you’re saying. How could that possibly be exploited for a side channel attack, though? All it would tell an attacker is that someone requested the file before.


The cache used to be shared between domains but that's no longer the case due to privacy concerns and limited effectiveness.

> As of Firefox v85 and Chrome v86 the browser cache will be partitioned, this means that the same resource included on two sites will have to be downloaded from the internet twice and cached separately.

Source https://www.peakhour.io/blog/cache-partitioning-firefox-chro....


This still helps other requests to the same origin, which is a very common situation if you don’t have the extra resources needed to get an SPA up to the same performance and reliability levels.


In practice I think downloading many small files is actually slower than a single bigger file. It might not be so true today with http2 for example though.


HTTP/2 definitely changed that and is near-universally supported now. The biggest win is the ability to cache things independently: with bundles your servers and clients have to retransfer everything if a single byte changes, and most of the sites I’ve worked on don’t change most of their files every time they ship an update. A cold visit will usually be immeasurably different from a bundle but a warm visit is noticeably faster.


Yes, it's much slower pre-http2 since no modern browser actually does pipelining, so it's going to be a socket per file

HTTP2 fixes this by allowing multiple requests to occur in parallel on a single connection.


In the specific case of JS import, it's still going to be pretty bad though, I guess, since you have to download a file, parse it to figure out the deps, then fetch them, parse them, etc, so you are limited in what you can do in parallel.


That’s what `modulepreload` &co is for. It’s a shame HTTP Push is dead, it was a much more general solution. But specifically for web pages the solution is more or less the same + 1 round trip (you won’t get the benefits of “push” until you at least process all the head>meta tags).


We already do this with a build step using a vendor bundle and an app bundle and it can be configured to create a bundle for each page.


>I use ES Modules for all my front end development and I get nothing but praise for how snappy my web applications are compared to the competition.

Word up. Share a link? I feel like the pro-ESM crowd shoudl stick together!


I think the trick is mostly not to have a shitload of dependencies. If you have to load a bunch of huge frameworks, whether it's bundled or you have to download thousands of files one by one, it's going to be slower than not doing it at all :)


It depends on your bundler and config. You might have “zero” dependencies, but depending on how the code is split you might end up with thousands of small imports nested quite deeply.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: