admin管理员组

文章数量:1415119

I have a problem regarding lighthouse issue on my angular app with lazy loading. Basically my app contains 3 big chunks of feature that should be lazy loaded. So when you open the feature A, I expect the app not to load the scripts for feature B and C at all, and vice versa.

But somehow, when I check with lighthouse, it reports back that I can "remove unused JavaScript" on the other JS files that contains the whole functionality of the other features. Even worse, one of the feature depends on ngx-quill for rich-text editor, and this also got loaded although I open a feature that does not need it.

Am I missing something here?

EDIT:

I have these following *-routing.modules.ts:

  • app-routing
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: '', loadChildren: () => import('./feature-a/feature-a.module').then(m => m.FeatureAModule) },
  { path: 'feature-b', loadChildren: () => import('./feature-b/feature-b.module').then(m => m.FeatureBModule) },
  { path: '**', redirectTo: '', pathMatch: 'full' }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }
  • feature-a: nothing of interest, no lazy loading here.

  • feature-b:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LandingPageComponent } from './pages/landing-page/landing-page';
import { FeatureBPage } from './feature-b.page';

const routes: Routes = [
  {
    path: '',
    ponent: FeatureBPage,
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      { path: 'home', ponent: LandingPageComponent },
      {
        path: 'feature-c',
        loadChildren: () =>
          import('./feature-c/feature-c.module').then(
            (m) => m.FeatureCModule
          ),
      },
      { path: '**', redirectTo: '', pathMatch: 'full' }
    ],
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class FeatureBRoutingModule {}
  • feature-c: contains multiple other lazy loaded features (feature-c1, -c2, -c3, etc), but none of those are being referenced by Feature A and/or Feature B.

I have a problem regarding lighthouse issue on my angular app with lazy loading. Basically my app contains 3 big chunks of feature that should be lazy loaded. So when you open the feature A, I expect the app not to load the scripts for feature B and C at all, and vice versa.

But somehow, when I check with lighthouse, it reports back that I can "remove unused JavaScript" on the other JS files that contains the whole functionality of the other features. Even worse, one of the feature depends on ngx-quill for rich-text editor, and this also got loaded although I open a feature that does not need it.

Am I missing something here?

EDIT:

I have these following *-routing.modules.ts:

  • app-routing
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
  { path: '', loadChildren: () => import('./feature-a/feature-a.module').then(m => m.FeatureAModule) },
  { path: 'feature-b', loadChildren: () => import('./feature-b/feature-b.module').then(m => m.FeatureBModule) },
  { path: '**', redirectTo: '', pathMatch: 'full' }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }
  • feature-a: nothing of interest, no lazy loading here.

  • feature-b:

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LandingPageComponent } from './pages/landing-page/landing-page';
import { FeatureBPage } from './feature-b.page';

const routes: Routes = [
  {
    path: '',
    ponent: FeatureBPage,
    children: [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      { path: 'home', ponent: LandingPageComponent },
      {
        path: 'feature-c',
        loadChildren: () =>
          import('./feature-c/feature-c.module').then(
            (m) => m.FeatureCModule
          ),
      },
      { path: '**', redirectTo: '', pathMatch: 'full' }
    ],
  },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class FeatureBRoutingModule {}
  • feature-c: contains multiple other lazy loaded features (feature-c1, -c2, -c3, etc), but none of those are being referenced by Feature A and/or Feature B.
Share Improve this question edited Apr 21, 2021 at 14:23 Vincentius Daniel asked Apr 16, 2021 at 17:06 Vincentius DanielVincentius Daniel 1681 silver badge12 bronze badges 7
  • 1 are you sure you defined these modules as lazy? could you provide your app-routing.module.ts file? – vitaliy kotov Commented Apr 16, 2021 at 18:37
  • @vitaliykotov I updated my question with the routing-modules files. Thanks! – Vincentius Daniel Commented Apr 21, 2021 at 14:24
  • I think your LandingPageComponent should also be in a seperate module, just like your FeatureCModule. And yes this module contains only 1 page, but the dependencies for this page will not automatically be imported in sibling pages. I guess this is what Lighthouse is plaining about... – Pieterjan Commented Apr 21, 2021 at 16:31
  • 1 @Pieterjan yes exactly, that I understand. What I do not understand is, when I visit /feature-b, the JS for feature-a and feature-c also get downloaded :/ – Vincentius Daniel Commented Apr 21, 2021 at 20:03
  • 1 You're right. Did you perhaps use PreloadAllModules in your RouterModule.ForRoot call? However AFAIK Lighthouse should not plain if that's the case... – Pieterjan Commented Apr 22, 2021 at 16:47
 |  Show 2 more ments

1 Answer 1

Reset to default 2

Looks like the issue is not so much with the unused JavaScript from bundles (scripts) that should not be loaded, but the fact that those bundles are being loaded in the first place.

It's hard to say without further details, but it could be for any of the following reasons:

  1. PreloadAllModules strategy loads all lazy-loaded modules regardless of their lazy-loading status.
  2. "Accidentally" importing something from one lazy-loaded feature module into another module loads that entier lazy-loaded module at run-time.
  3. Verify through the Network tab that the unrelated lazy-loaded features are indeed being loaded (and you are not confusing other files for them).
  4. In case the unused JavaScript is in the bundles that should, in fact, be loaded, Lighthouse reports any piece of code that wasn't executed (e.g. if conditions that didn't run, *ngIf directives that didn't execute) as unused. There isn't much one can do about that.

本文标签: