> The browser must request each JavaScript file individually. In a large codebase, this can result in thousands of HTTP requests in order to render a single page. In the past, prior to HTTP/2, this would also result in thousands of TLS handshakes.
> In addition, several sequential network round trips may be needed before all the JavaScript is loaded. For example, if index.js imports page.js and page.js imports button.js, three sequential network round trips are necessary to fully load the JavaScript. This is called the waterfall problem.
In general the number of requests is not the current (in HTTP2/3) problem. In HTTP1 browsers limited the concurrent requests to each domain to 6, so if you had more than 6 resources you had to wait for a slot (this is head of line blocking). This was supposed to be fixed in HTTP1 with HTTP pipelining, but that never took off and support is basically non-existent. If your server was properly configured (with keep-alive) this still would not lead to additional TCP/TLS handshakes.
With HTTP2/HTTP3 the head of line blocking is fixed by multiplexing all requests over one connection, so the problem is more discovery/waterfall and compression than the number of requests.
Discovery/waterfall problem: If file A loads file B which loads file C you cannot know to start loading C until first A has loaded, then B, and then C (and this chain will probably be a lot deeper in most modern frontend apps). The idea to fix this was via either Server Push (which is sorta deprecated and removed) or HTTP 103 Early Hints (which would allow you to send preload hints before sending the actual server response). If File A loads B and C directly then the impact is much lower.
Compression: If file B and file C contain similar code (like a lot of frontend components do) then the result of individually compressing B and C is a lot larger than keeping them in the same file and compressing the combination. SDCH (Shared Dictionary Compression for HTTP) was supposed to fix this by allowing you to have a compression dictionary that could be used by many files but that was only implemented in chrome (which has since removed it) and basically only used by linkedin. A similar idea is present in brotli, where there is a single standardized shared dictionary based on common text on the web, and I think there has been some talk about how to revive this for zstd on the web.
So, the number of requests are usually not the issue, and if you used Server Push or Early Hints combined with SDCH you could have pretty close to the performance of bundling without build systems. But that ship sailed long ago with the deprecation and removal of Push and SDCH
It also has some additional use cases. You can now also do delta compression, where as an asset updates the server only has to ship deltas.
Amusingly this could also be extremely useful for bundlers. But I do hope we see modules on the web happen. With http3 and early hints and deferred imports (required to improve time to load, recently advanced to stage 2.7), it feels like the window of possibility is reopening.
Good news! Mozilla seems to be updating their zstd position to positive, after compression dictionary work unblocked there concerns about dictionaries. As of 4 days ago! https://github.com/mozilla/standards-positions/pull/1042
> In addition, several sequential network round trips may be needed before all the JavaScript is loaded. For example, if index.js imports page.js and page.js imports button.js, three sequential network round trips are necessary to fully load the JavaScript. This is called the waterfall problem.
In general the number of requests is not the current (in HTTP2/3) problem. In HTTP1 browsers limited the concurrent requests to each domain to 6, so if you had more than 6 resources you had to wait for a slot (this is head of line blocking). This was supposed to be fixed in HTTP1 with HTTP pipelining, but that never took off and support is basically non-existent. If your server was properly configured (with keep-alive) this still would not lead to additional TCP/TLS handshakes.
With HTTP2/HTTP3 the head of line blocking is fixed by multiplexing all requests over one connection, so the problem is more discovery/waterfall and compression than the number of requests.
Discovery/waterfall problem: If file A loads file B which loads file C you cannot know to start loading C until first A has loaded, then B, and then C (and this chain will probably be a lot deeper in most modern frontend apps). The idea to fix this was via either Server Push (which is sorta deprecated and removed) or HTTP 103 Early Hints (which would allow you to send preload hints before sending the actual server response). If File A loads B and C directly then the impact is much lower.
Compression: If file B and file C contain similar code (like a lot of frontend components do) then the result of individually compressing B and C is a lot larger than keeping them in the same file and compressing the combination. SDCH (Shared Dictionary Compression for HTTP) was supposed to fix this by allowing you to have a compression dictionary that could be used by many files but that was only implemented in chrome (which has since removed it) and basically only used by linkedin. A similar idea is present in brotli, where there is a single standardized shared dictionary based on common text on the web, and I think there has been some talk about how to revive this for zstd on the web.
So, the number of requests are usually not the issue, and if you used Server Push or Early Hints combined with SDCH you could have pretty close to the performance of bundling without build systems. But that ship sailed long ago with the deprecation and removal of Push and SDCH