-
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
bug: all RxJS operators pulled into prod bundle when using lettable imports from 'rxjs/operators' #9069
Comments
I'll look into this |
The problem is that you have If things go as planned webpack 4 should significantly improve this situation, but until then definitely always always turn off vendor chunking if you care about payload size. This is why |
I'm not using My env for staging is the following: export const environment = {
production: true,
firebaseConfig: { ... },
googleAnalyticsTrackingId: '...',
mapsApiKey: '...'
} I'll post the source map explorer screenshots in a minute. |
According to https://github.com/angular/angular-cli/wiki/build, Perhaps the issue is that the default should now be |
@Splaktar is your project public maybe? That way I could take a look. Are you using lazy bundles as well? Can you try removing them and checking if there's a difference in rxjs? |
@filipesilva the source isn't public. The staging and production sites are. There is currently one major lazy loaded module. The other routes just go to simple components that are fairly static. const routes: Routes = [
{path: '', pathMatch: 'full', component: LandingComponent, children: []},
{path: 'agents', loadChildren: './agents/agents.module#AgentsModule'},
{path: 'profile/:id', component: ProfileComponent, canActivate: [UsersService], children: []},
{path: 'terms', component: TermsComponent, children: []},
{path: 'privacy', component: PrivacyComponent, children: []},
{path: '**', component: PageNotFoundComponent, children: []}
];
@NgModule({
imports: [RouterModule.forRoot(routes, {useHash: false})],
exports: [RouterModule],
providers: []
})
export class AppRoutingModule {} |
If you turn that lazy route into a normal route, or remove it altogether, does the rxjs size in the main bundle change? |
Note that some operators come from libraries. So they are still needed in the bundle even if you don't use them directly. |
In the |
@Splaktar can you create a minimal reproduction similar to how @Toxicable created the one earlier? I see that you are using firebase in your app and you are using the cjs distro of that library. I'm wondering if that's why all the operators are retained. A minimal reproduction would confirm or reject that theory. |
I'm using "scripts": [
"../node_modules/hammerjs/hammer.js",
"../node_modules/firebase/firebase.js"
], It looks like I should be doing this instead: "scripts": [
"../node_modules/hammerjs/hammer.js",
"../node_modules/firebase/firebase-app.js",
"../node_modules/firebase/firebase-auth.js",
"../node_modules/firebase/firebase-database.js"
], But I'm not sure how much that will help. I looked at their web setup page and Firebase JS SDK GitHub and I don't see any way to pick different types of modules. I'll dig into that a bit more, try out firebase Update: Firebase |
Hm... importing |
OK, I've created a reproduction repo here. Time to get to sleep now... |
@Splaktar awesome, I was just putting up a repro myself. This way it's much easier. Will take a look. |
Running some baseline tests, measuring size of
I think having a lazy bundle is having the same effect on bundle size as the vendor chunk (described in #9069 (comment)). This makes sense because vendor chunk is not special, it's just another chunk, just like a lazy chunk is just another chunk. This makes me think that the best hope to address this problem is Webpack 4. Support is being tracked in #8611. Note: regarding #9069 (comment), when Build Optimizer is used then vendor chunk will default to false (https://github.com/angular/angular-cli/wiki/build#--build-optimizer-and---vendor-chunk) |
@filipesilva thank you very much for looking into this! Oh that's really interesting about Build Optimizer and Vendor Chunk options. Perhaps https://github.com/angular/angular-cli/wiki/build can be updated with that information? I guess at this point, we should recommend that teams do not use lettable operators if they are using the Angular CLI with lazy loaded routes (this is every developer as we have been telling them for a year+ to lazy load every possible route). Do you see any alternative to this? I need to advise multiple active clients on this atm in addition to my own projects. |
@Splaktar I remember facing this problem some time ago when importing from Maybe one option for you is to advice using deep imports (at least as a temporary solution). I've updated your reproduction from #9069 (comment) to use this approach and RxJS bundle size is back to normal. |
@devoto13 thank you very much for looking into that! It was a question that I was just asking myself. What you have shown though is that using lettable operators with deep imports is not a solution for "saving considerably on bundle size". I can't advise my clients to add a considerable amount of boilerplate (yes it can be auto filled by IDEs in most cases) and change to a new syntax if there is no significant impact on bundle size. I'm going to push up a branch w/o lettable operators for comparison. |
@Splaktar Thanks! Please do. Will be very interesting to see how much better it gets without lettable operators. |
I don't expect it to be better w/o lettable operators other than that it matches most of the existing docs and apps that are out there today. The issue is that it's not clear how lettable operators are "considerably better" in Angular w/ the Angular CLI today. Non-lettable operator branch (i.e. old fashioned): https://github.com/DevIntent/angular-example/tree/withoutLettableOperators The only difference that I can see is the savings of the |
any news on that? Rxjs documentation states bundle size can be fixed through Webpack configuration. Is that intended to be fixed through webpack 4 upgrade? |
I just found this issue (should have looked for it earlier...) after spending my morning trying to figure out why I had all of rxjs being bundled on our app (@angular/cli": "1.6.7") Also I haven't checked thouroughly yet but it seems like we have the same tree shaking problem with date-fns/esm pulling everything into the prod bundle. I'll second @blackholegalaxy with his/her question, or if anyone can point us to an issue where we can track / fix this ? Thanks ! |
@blackholegalaxy @Lakston this the the correct issue to track resolution. The only way to truly achieve tree shaking of RxJs (in the current context) is to use Webpack 4 and have the package marked as being side effect free. Without these two preconditions, it is only possible to treeshake RxJs operators in the main bundle, and only if the vendor bundle is disabled (as it is by default on prod builds). |
Sorry about my lack of knowledge of the "under the hood angular CLI logic", but could the solution on the link I provided above, by Rxjs team, work in the CLI context? It seems CLI relies on webpack 3 right? |
@blackholegalaxy we already implement that in the CLI actually. |
Ok nice to know. We will then wait for webpack 4 improvements. Thanks for precision @filipesilva :) |
If you have Most applications use between 8-20 operators. I'd estimate the average is around 12-15. |
still have this issue in Angular CLI 6 with rxjs6 with no rxjs-compact. |
I found this issue because I was also experiencing this issue with a custom Webpack 4 + Babel 6 setup. I then tried Rollup just for fun to see if it makes any difference. Using RxJS and one/two pipeable operators resulted in a ~10 kb bundle with Rollup. Webpack on the other hand created a 120 kb bundle. But I noticed that Rollup requires the following line in {
"presets": [
[
"env",
{
"modules": false // <- this
}
]
]
} After adding this line in the Now I guess the Angular CLI uses TypeScript instead of Babel. From reading the documentation it seems to have a similar option in I didn't try this (and I don't have any Angular projects right now) but maybe this helps you finding a solution? But at least to me this also means that this is not necessarily a Webpack issue, right? |
Having this issue as well with all rxjs in my bundle, as well as all lodash-es when I only use 2 imports Rx: 6.3.3 |
@juarezpaf One of the possibilities why this could be happening is that one of the deps libraries that you use also has |
I'm not sure when the exact fix went in, but this is no longer an issue in Angular CLI |
Facing similar issue Environment: Note I just want to get rid of this 900+ KB sized thing. |
@KishoreBarik this issue is closed. Please open a new issue and link to this issue from your new issue. |
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. |
Versions
Repro steps
https://github.com/Toxicable/issue-lettable-bundle-size
Observed behavior
From #8854 (comment), "There appears to be a bug in Webpack that is causing the CLI to import all of the RXJS operators if you use any lettable operator imports without doing each as a deep import individually.
Upgrading to lettable operators in CLI 1.6.3 caused RxJS to go from 60 KB to 122 KB for me. It sounds like a fix is 'coming soon', but I haven't been able to track down the issue to follow."
Another user mentioned a bundle size increase when moving to lettable operators in the CLI: #8720 (comment)
Desired behavior
From the 5.0 blog post:
"These new operators eliminate the side effects and the code splitting / tree shaking problems that existed with the previous ‘patch’ method of importing operators."
"RxJS now distributes a version using ECMAScript Modules. The new Angular CLI will pull in this version by default, saving considerably on bundle size."
I desire a considerable reduction in bundle size, not an increase.
Mention any other details that might be useful (optional)
I tracked this down across Slacks, GitHub, and Twitter as I was told that there was a known Webpack problem that would be fixed soon and then pulled into the CLI. As far as I can tell, any similar Webpack issue was solved in
3.9.0
and the current CLI already includes it as it is using3.10.0
now.I can provide source map explorer screenshots if needed, but the linked repo above should enable you to better reproduce and create your own source map explorer output.
RxJS Docs for lettable operators and builds: https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md#build-and-treeshaking
Workaround
Breaking out all of your imports into individual (one import per line) deep imports seems to avoid this issue, but it is very painful and not desirable to have these extra lines of imports in projects of any significant size or scope.
The text was updated successfully, but these errors were encountered: