在使用路由延迟加载中,我们介绍了如何使用模块来拆分应用,在访问到这个模块的时候, Angular 加载这个模块。但这需要一点时间。在用户第一次点击的时候,会有一点延迟。
我们可以通过预加载路由来修复这个问题。路由可以在用户与其它部分交互的时候,异步加载延迟的模块。这可以使用户在访问延迟模块的时候更快地访问。
本文将在上一个示例的基础上,增加预加载的功能。
在上一节中,我们的根路由定义在 main.routing.ts,我们在 app.module.ts 中使用了根路由定义。
需要注意的是,Home 组件是提前加载的。我们将在系统启动之后渲染这个组件。
在 Angular 渲染 Home 组件之后,用户就可以与应用交互了,我们可以通过简单的配置在后台预加载其它模块。
启用预加载
我们在 forRoot 函数中,提供一个预加载的策略。
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; import { routes } from './main.routing'; import { RouterModule } from '@angular/router'; import { PreloadAllModules } from '@angular/router'; @NgModule({ declarations: [ AppComponent, HomeComponent ], imports: [ BrowserModule, RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules }) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
这个 PreloadAllModules 策略来自 @angular/router,所以我们还需要导入它。
定制预加载策略
router 包中预定义了两个策略:
5 秒之后加载模块
但是,您可以自己定义一个定制的策略。这比您想的要更为简单。例如,您希望在应用初始化 5 秒之后加载其余的模块。
您需要实现接口 PreloadingStrategy,我们定义一个 CustomPreloadingStrategy 的自定义策略类。
import { Route } from '@angular/router'; import { PreloadingStrategy } from '@angular/router'; import { Observable } from 'rxjs/Rx'; export class CustomPreloadingStrategy implements PreloadingStrategy { preload(route: Route, fn: () => Observable<boolean>): Observable<boolean> { return Observable.of(true).delay(5000).flatMap((_: boolean) => fn()); } }
然后,修改 app.module.ts 使用这个自定义策略。需要注意的是,您还需要在 prodivers 中添加这个类。以实现依赖注入。
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; import { routes } from './main.routing'; import { RouterModule } from '@angular/router'; import { CustomPreloadingStrategy } from './preload'; @NgModule({ declarations: [ AppComponent, HomeComponent ], imports: [ BrowserModule, RouterModule.forRoot(routes, { preloadingStrategy: CustomPreloadingStrategy }) ], providers: [CustomPreloadingStrategy ], bootstrap: [AppComponent] }) export class AppModule { }
你会看到 在 5 秒钟之后,这个功能模块被自动加载了。
加载指定模块
我们还可以在路由中定义附加的参数来指定哪些模块进行预加载,我们使用路由定义中的 data 来提供这个附加的数据。
import { Routes } from '@angular/router'; // HomeComponent this components will be eager loaded import { HomeComponent } from './home/home.component'; export const routes: Routes = [ { path: '', component: HomeComponent, pathMatch: 'full' }, { path: 'shop', loadChildren: './shop/shop.module#ShopModule', data: {preload: true} }, { path: '**', component: HomeComponent } ];
然后,我们定义新的加载策略。
import { Observable } from 'rxjs/Rx'; import { PreloadingStrategy, Route } from '@angular/router'; export class PreloadSelectedModules implements PreloadingStrategy { preload(route: Route, load: Function): Observable<any> { return route.data && route.data.preload ? load() : Observable.of(null); } }
最后,在 app.module.ts 中使用这个策略。
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; import { routes } from './main.routing'; import { RouterModule } from '@angular/router'; import { PreloadSelectedModules } from './preload.module'; @NgModule({ declarations: [ AppComponent, HomeComponent ], imports: [ BrowserModule, RouterModule.forRoot(routes, { preloadingStrategy: PreloadSelectedModules }) ], providers: [PreloadSelectedModules ], bootstrap: [AppComponent] }) export class AppModule { }
此时,可以看到,模块直接被预加载了。即使您点击链接,也不会再有新的请求发生。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
为了显示这种关系,让我们开始定义一个简单的模块,作为我们的示例应用程序的根模块。 app/app.module.ts 到目前为止,这是一个非常常见的模块,依赖于,有一个路由机制和两个组件:AppComponent和EagerComponent。 现在,让我们专注于定义导航的应用程序(AppComponent)的根组件。 app/app.component.ts import { Component
问题内容: 感谢Dan Wahlin的精彩文章,我设法实现了Angular的控制器和服务的延迟加载。但是,似乎没有一种干净的方法来懒惰加载独立的模块。 为了更好地解释我的问题,假设我有一个没有RequireJS的应用,其结构如下: 这是在Plunker中带有RequireJS的示例应用程序:http ://plnkr.co/aiarzVpMJchYPjFRrkwn 问题的核心是Angular不允许
我试图实现延迟加载,但得到如下错误** 错误错误:未捕获(在promise中):错误:BrowserModule已加载。如果您需要从一个延迟加载的模块中访问一些公共指令,比如NgIf和NgFor,那么可以导入CommonModule。 ** 需要帮助这是我的模块 共享模块 2.设置模块 5.AppModule
本文向大家介绍Webpack 实现 AngularJS 的延迟加载,包括了Webpack 实现 AngularJS 的延迟加载的使用技巧和注意事项,需要的朋友参考一下 随着你的单页应用扩大,其下载时间也越来越长。这对提高用户体验不会有好处(提示:但用户体验正是我们开发单页应用的原因)。更多的代码意味着更大的文件,直到代码压缩已经不能满足你的需求,你唯一能为你的用户做的就是不要再让他一次性下载整个应
本文向大家介绍浅析js预加载/延迟加载,包括了浅析js预加载/延迟加载的使用技巧和注意事项,需要的朋友参考一下 Pre loader 预加载一般有两种常用方式:xhr和动态插入节点的方式。动态插入节点是最为简单也最为广泛的一种异步加载方式,然后使用动态插入节点方法加载的文件都会 在加载后立即执行,javascript的执行一方面会占用浏览器js执行进程,另一方面也可能改变页面结构,而css 的执行
本文向大家介绍AngularJS中的Directive实现延迟加载,包括了AngularJS中的Directive实现延迟加载的使用技巧和注意事项,需要的朋友参考一下 所谓的延迟加载通常是:直到用户交互时才加载。如何实现延迟加载呢? 需要搞清楚三个方面: 1、html元素的哪个属性需要延迟加载? 2、需要对数据源的哪个字段进行延迟加载? 3、通过什么事件来触发延迟加载? 自定义的Directive