angular: Preloading modules are freezing the UI

We are preloading “lazy-loaded modules” to reduce initial payload and improve the app startup time. So that, we have decided to use “PreloadAllModules Strategy”.

But the problem is when we try to preload the modules it loads them in the background asynchronously which is good but then the UI looks frozen while the loaded scripts are getting executed and the current user interaction is not smooth until the preloaded lazy modules execution is complete.

It looks like since the javascript is single threaded it is halting the current execution of whatever user is interacting with and trying to load and execute the asynchronously loaded modules which is what causing freeing of UI.

Are there any alternatives to this problem or any work around to this problem while we still take advantage of preloading without freezing the UI.

My current scenario is something like below:

  1. First the login page is loaded and then after successful login redirected to home page and the user tries to interact with the application.
  2. I am trying to preload the lazy loaded after 5 seconds delay after my app is loaded so that the user is able to interact with the login page withot delay.
  3. When user is trying to interact with the home page after the lazy loaded scripts are loaded it immediately trying to execute the loaded scripts and delaying the current interaction of the user which makes it less responsive or interactive which is not desirable.

Here is the Custom Preloading strategy I am using to delay the loading of Prealoading Modules.

import * as _ from ‘lodash’; import { AppService } from ‘…/…/app.service’; import { Injectable } from ‘@angular/core’; import { Observable, of, timer } from ‘rxjs’; import { PreloadingStrategy, Route } from ‘@angular/router’; import { tap } from ‘rxjs/operators’;

@Injectable({ providedIn: ‘root’ })

export class CustomPreloadingStrategy implements PreloadingStrategy {

constructor(private appService: AppService) { }

preload(route: Route, load: () => Observable<any>): Observable<any> {
    return timer(5000).pipe(
        tap(() => {
                return _.flatMap.call(load(), () => of(null));
        })
    );
}

}

Now the problem is after the login is screen is loaded

🐞 bug report

Is this a regression?

NO

Description

A clear and concise description of the problem...

🌍 Your Environment

6.0.5





Anything else relevant?

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16 (2 by maintainers)

Most upvoted comments

I’m confused why we are talking about JIT here - compilation of Angular templates is expensive so I wouldn’t be surprised in a browser is busy during this time. But in the prod mode all modules should be loaded asynchronously and be already AOT-compiled. Doing any perf measurements in the JIT mode is just missing the point - it is the dev mode facility only.

I’m going to close this one as I don’t think there is anything actionable here - unless someone can provide a minimal reproduce scenario illustrating significant perf degradation with lazy-loaded modules in the AOT/ prod mode.

The preload function should take boolean or something to tell it only to download and not execute the module, and only execute the module when needed.

Edit: This solves initial freezing and reduces the delay when lazy loading a module.

Use cases: 1: Faster initial download and view times 2: Preload modules we know the user has access to

@pkozlowski-opensource

Had the same problem in my modest 20ish modules application. Setting preloadingStrategy to “NoPreloading” nullifies startup freezes (you still have a tiny freeze everytime you load a new module), but using AOT compilation with it really speed things up seemingly removing all the freezes.

I also don’t think a “PreloadAllModules” strategy (or anything similar) is usually a good idea; why would you preload modules that your user might not call while browsing your application? Sounds like a waste of bandwidth to me