1

I have an app I recently upgraded to Angular 11, and I wanted to improve performance so I added in a core module (just for services, imported in root module), shared module (imported in many feature modules), and some feature modules, and I load the feature modules lazily. I see that I have chunks generated for each of the feature modules, as expected, but there is also a ton of default chunks. I am not concerned that there are default chunks, but what confuses me is that I have 4 default chunks for the same module:

screenshot of the chunks after building

Why would there be four of the same one, and is this an issue? This is whats inside of that particular feature module (ArchivedProposalManagerModule):

import { NgModule } from '@angular/core';
import { ArchivedProposalManager } from './archived-proposal-manager.component';
import { ArchivedProposalManagerRoutingModule } from './archived-proposal-manager-routing.module';
import { FormFeatureModule } from '../../proposal-form-feature/proposal-form-feature.module';

@NgModule({
  declarations: [
    ArchivedProposalManager
  ],
  imports: [
    ArchivedProposalManagerRoutingModule,
    FormFeatureModule
  ],
  providers: [],
  exports: []
})
export class ArchivedProposalManagerModule { }

FormFeatureModule:

import { NgModule } from '@angular/core';
import { SharedModule } from '../shared/shared.module';
import { ProposalsDashboardComponent } from '../nssr-components/incoming-proposals-manager/proposals-dashboard.component';
import { ProposalManagerComponent } from '../nssr-components/proposal-estimation-manager/proposal-manager.component';
import { StandardEstimatesFormComponent } from '../nssr-components/proposal-estimation-manager/standard-estimates-form/standard-estimates-form.component';
import { NonStandardEstimatesFormComponent } from '../nssr-components/proposal-estimation-manager/non-standard-estimates-form/non-standard-estimates-form.component';
import { OneTimeChargesFormComponent } from '../nssr-components/proposal-estimation-manager/one-time-charges-form/one-time-charges-form.component';
import { RequestEditableFieldsComponent } from '../nssr-components/incoming-proposals-manager/Request-editable-fields-component/Request-editable-fields-component';
import { FileUploadModule } from 'ng2-file-upload';
import { AgGridFeatureModule } from '../ag-grid-feature/ag-grid-feature.module';

@NgModule({
  declarations: [
    ProposalsDashboardComponent,
    RequestEditableFieldsComponent,
    ProposalManagerComponent,
    StandardEstimatesFormComponent,
    NonStandardEstimatesFormComponent,
    OneTimeChargesFormComponent
  ],
  imports: [
    FileUploadModule,
    SharedModule,
    AgGridFeatureModule
  ],
  providers: [],
  exports: [
    FileUploadModule,
    SharedModule,
    ProposalsDashboardComponent,
    RequestEditableFieldsComponent,
    ProposalManagerComponent,
    StandardEstimatesFormComponent,
    NonStandardEstimatesFormComponent,
    OneTimeChargesFormComponent,
    AgGridFeatureModule
  ]
})
export class FormFeatureModule { }

SharedModule:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgxSmartModalModule } from 'ngx-smart-modal';
import { FormsModule, ReactiveFormsModule} from '@angular/forms';
import { MaterialFeatureModule } from '../material-feature/material-feature.module';
import { HttpClientModule } from '@angular/common/http';
export { FormControl , FormGroup, FormBuilder, Validators, FormArray} from '@angular/forms';
   
@NgModule({
  declarations: [
  ],
  imports: [
    CommonModule,
    FormsModule,
    HttpClientModule,
    MaterialFeatureModule,
    NgxSmartModalModule.forRoot(),
    ReactiveFormsModule,
    ReactiveFormsModule.withConfig({ warnOnNgModelWithFormControl: 'always' })
  ],
  exports: [
    CommonModule,
    FormsModule,
    HttpClientModule,
    MaterialFeatureModule,
    NgxSmartModalModule,
    ReactiveFormsModule
  ],
  providers:[]
})
export class SharedModule { }

I'm having a hard time understanding if this is expected or if I'm doing something wrong in the code. I tried to look it up and I see that default chunks are generated because of common modules - there are many other feature modules I have that also use SharedModule and FormFeatureModule, but only this one (ArchivedProposalManager) is seen in the default chunks.

Additionally, because of the upgrade and the lazy loading, the deployment zip file is twice as large now (used to be 21mg, now 43mb). I am assuming this is fine seeing as it won't be loading everything at once anyway due to being lazy loaded, but the default chunks are upping this size.

Edit: I got it down to 33mb, realized I didn't clear out the 'publish' folder where these files all get stored before running my publish command, as it didn't remove the previous files, only was overwriting those that existed.

I've seen people recommend to use commonChunk: false in angular.json to not have defaults but this clearly isn't working. I don't care to remove them if they are necessary/helpful, but I want to confirm that having four of these default chunks for the same module is normal. Is this anything to do with the way webpack could be set up?

this is in my angular.json:

"configurations": {
    "production": {
      "optimization": true,
      "outputHashing": "all",
      "sourceMap": false,
      "namedChunks": true,
      "commonChunk": false,
      "aot": true,
      "extractLicenses": true,
      "vendorChunk": false,
      "buildOptimizer": true,
      "fileReplacements": [
        {
          "replace": "src/environments/environment.ts",
          "with": "src/environments/environment.prod.ts"
        }
      ]
    }
  }

My dependencies in package.json:

  "dependencies": {
    "@angular/animations": "^11.2.14",
    "@angular/cdk": "^11.2.13",
    "@angular/common": "^11.2.14",
    "@angular/compiler": "^11.2.14",
    "@angular/core": "^11.2.14",
    "@angular/forms": "^11.2.14",
    "@angular/language-service": "^11.2.14",
    "@angular/material": "^11.2.13",
    "@angular/platform-browser": "^11.2.14",
    "@angular/platform-browser-dynamic": "^11.2.14",
    "@angular/router": "^11.2.14",
    "@ng-bootstrap/ng-bootstrap": "^9.0.0",
    "@syncfusion/ej2-angular-richtexteditor": "^19.4.56",
    "ag-grid-angular": "^19.1.2",
    "ag-grid-community": "^19.1.2",
    "aspnet-prerendering": "^3.0.1",
    "bootstrap": "^4.3.1",
    "build": "^0.1.4",
    "core-js": "^2.4.1",
    "file-saver": "^2.0.2",
    "font-awesome": "^4.7.0",
    "material-icons": "^1.4.1",
    "moment": "^2.29.1",
    "ng": "^0.0.0",
    "ng2-file-upload": "^1.4.0",
    "ngx-smart-modal": "^7.2.1",
    "rxjs": "^6.6.7",
    "tslib": "^2.4.0",
    "web-animations-js": "^2.3.2",
    "webpack": "^4.44.2",
    "zone.js": "^0.10.3"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1102.19",
    "@angular/cli": "^11.2.19",
    "@angular/compiler-cli": "^11.2.14",
    "@types/mocha": "^9.1.1",
    "@types/node": "~6.0.60",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~6.3.20",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~7.0.0",
    "ts-node": "~4.1.0",
    "tslint": "^6.1.3",
    "typescript": "^4.1.6"
  },
  "optionalDependencies": {
    "node-sass": "^4.9.0"
  }

As an additional point if its relevant, I use the following command to create a deployment which creates my build files/chunks:

dotnet publish "NSSR.csproj" -c Release

This is an Angular/.NET application. I run that command, then zip up the contents.

Very long post but hopefully its enough detail! Thank you

  • you done have to worry about the extra chunks so much. its more about when loading the individual pages. Now i will say to minimize loads size of bundles i found that doing the SCAM approach to be a bit better. Since it can be hard to control what components you want as part of the shared library. And you tend to end up with extra stuff not needed. – Henrik Bøgelund Lavstsen May 21 '22 at 04:04
  • @HenrikBøgelundLavstsen thanks for your comment, I checked out this article https://sandroroth.com/blog/angular-shared-scam and under the tree shaking section it seems to imply that if you have ivy engine it uses tree shaking to prevent unused stuff so the SCAM approach doesn't have much of an advantage in that sense? – kiwrezc2000 May 21 '22 at 04:43
  • It should but I have seen in the downloaded bundles components that i didn't use. So maybe it can but i dont think its perfect – Henrik Bøgelund Lavstsen May 21 '22 at 05:11
  • @kiwrezc2000 - any new updates? I am in similar situation! – Aakash Goplani Jul 18 '22 at 16:03

0 Answers0