-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
application builder generates many initial chunks #26307
Comments
@jnizet that how esbuild works. If you don't use http/2 it's would be drop in core web vitals. esbuild has open issue evanw/esbuild#207 but that is not implemented. If you have http/2 setup that amount of chunks not an issue for you |
Indeed this is expected, this is becasue esbuild does cross chunk code motion which webpack does not, which results in a more smaller chunks. When using HTTP/2 or HTTP/3 the number of files does not have any performance penalty. |
OK. Too bad this isn't considered. |
@jnizet, containing the chunks will actually cause unnecessary code to be downloaded when navigating to a particular page. Thus, for a performance perspective, having a lot of chunks should be better if using modern HTTP protocols. Although I do see that sometimes esbuild does generate super small chunks under 1 kb, but that is by esbuild design. Concatenating chunks is definitely not something the Angular CLI should be doing. The bundler has the full context of how chunks should be split to download as code as possible. |
@alan-agius4 when you say Our website shows very bad performance after upgrading to angular 17. Lighthouse reports too many chained requests (150 chunks!): |
@elgerm you are right, but check my message above, try to upgrade your http to http/2 or better http/3 to get better performance, because http 1.1 has only 6 parallel connections in browser (that IS reason why concatenation in vendor chunk exist) while http/2 has 100 |
Hi @elgerm, Which HTTP version are you using? In the case of HTTP 1 it is expected that there is a performance regression. It is also important mentioning that lighthouse should not be ran against a the local dev-server. Esbuild performs code motion and splits the code based on it's usage which does create more chunks. This is described here: https://github.com/evanw/esbuild/blob/main/docs/architecture.md#code-splitting. Webpack has less chunks as it's unable to perform this sort of advanced optimization. What is the lighthouse score before and now? |
Hi guys, Lighthouse score went down from 70ish to 39. We're behind cloudflare and have http3 enabled. I switched back to 16 for now as this was unacceptable performance. We get about 50k daily unique visitors from SE Asia, 33% use old devices and may find this unusable. Hence the question if it has been tested that so many small chunks don't degrade performance. There must be a penalty from loading and bootstrapping so many small chunks? Angular went from module based to component based and now switched to esbuild that now generates a chunk per component/directive/pipe. There's 450 chunks in the dist folder 🤯. Is it possible to go back to webpack build w 17? |
@elgerm its possíble to use webpack with 17 angular. Just use browser target, not browser-esbuild |
The lighthouse block
The old way (less & bigger chunks) is apparently worse as it's reported under But 152 files on initial load indeed does sound scary. Sadly esbuild has no |
Our system creates waay more than those 150 chunks, it's actually at 240+ initial chunks (and 472 lazy chunks). It is a rather large platform. It's still fast though, but I would like the preload to be reduced/delayed. Tbh, though Angular is made for larger systems. It often feels like the really really large systems like this are not being tested out well. (not trying to bash here, just how it feels, I still love angular and the way it works a lot) (Though it could just be that we should set things up differently, but there isn't much documentation about building a big system) |
Small project but a lot of dependencies that didn't combine their scripts which results in 698 chunks. I'm all for optimizing, but this is just weird. Especially seeing most are external dependencies which could very well be combined (or at least provide the option to do it). It currently serves 304 chunks for the first page of our project (most of it are external dependencies) |
what I really recommend to all as workaround is to use webpack for production and serve app for development with |
This is also an issue for us. Looks like we may need to revert to using webpack for production as well, as the chaining of chunks on initial load is causing non-trivial performance issues. |
same here, our server is http (not http/2) and so we need a way to keep total files same as webpack. Any updates? solutions? |
First step is look what is in those small chunks. Lets say it's lots of lodash-es code, because lodash is 200 little functions. You could use commonjs lodash instead. esbuild will still delete unused code, but won't rip it apart anymore, as it can't guarantee side effect freeness. If your 500 byte chunks contain simple strings, you could move those strings behind a barrel. e.g. if you have constants like here: // constants-a.ts
export const foo = 'foo string';
export const bar = 'bar string';
// constants-b.ts
export const lorem = 'lorem string';
export const ipsum = 'ipsum string'; you create a barrel like: // constants.ts
export * from './constants-a.ts';
export * from './constants-b.ts'; And if you So there are some ways to bend esbuild to your will. Third option might be, to contribute to esbuild something like a |
Honestly I commented because the amount of chunks can be insane, and imho should be improved with better bundling/lazy loading. but it is faster for us and working fine on chromebooks even. Cloudflare is caching it for free (and if you want you could even upload it to cloudflare workers) Probably an Unpopular opinion, solutions because people are still on http1 should imho not happen. Use webpack then or upgrade your servers. Http 2 is from may 2015 and almost 9 years old now. |
this issue is causing my colleagues to call me "the chunk man" |
This is the main reason yes. I would already be happy if I could force every module to be a chunk, so that with lazy routes it at least only needs to do one request. But its difficult to probably see what belongs where. For standalone stuff it will likely be even more difficult and the only one to tell esbuild to do better, is angular itself. Since it could figure out a dependency tree that can be used to optimize it. Perhaps using routes to bundle them or something.
You assume that every company owns their own servers or that their security/monitoring/etc tools can handle http2 already. Lets be real here, some bad admins can't be bothered or simply don't want to do anything about it. So having the option is always going to be of some benefit to people.
That or a dependency tree that can be used to figure out what is connected and can be bundled. With hot modules replacement / reloading, you already need to know what stuff needs to be reloaded with the changes you've made. |
How can we post-process this exponential explosion of files? Shipping ESBuild mode in Angular without built-in handling of chunks makes it highly disruptive. Apart from complicating debugging/diagnostics in browser, it rakes up deployment and support risks couple orders of magnitude.
Anecdotal case:
If Angular team is not ready to improve the situation at this point, can you folks please give us direction and help adding customisations/plugin/script to implement chunk coalescing at the project side? |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Command
build
Description
I just migrated a small project to v17 and the application builder.
The
ng build
command generates 13 initial (i.e. not lazy-loaded) bundles.I don't know if it's expected or not, but if it is, I don't understand the point of having so many initial bundles (the browser builder used to generate only 3).
Won't that automatically cause performance issues, given that browsers limit the number of concurrent requests to a given domain?
Describe the solution you'd like
Unless there is a good reason (that I'm currently missing) for so many bundles, I'd like the builder to generate fewer bundles: one for the polyfills (that could be cached for a long time) and one for the application for example.
If there is a good reason for so many bundles, please enlighten me :-)
Describe alternatives you've considered
No response
The text was updated successfully, but these errors were encountered: