本帖最后由 悟箜 于 2016-9-3 15:11 编辑
摘要
AngularJS 2.0 RC 5发布的同时Angular Router RC 1也同时发布,这其中包含了NgModule,也包含了Lazy Loading。今天我们就来看一下Angular 2 里的Lazy Loading。 文章中的代码已经整理上传到GitHub: https://github.com/WuKongW/Angular2_POC
就在我写这篇博客的时候,Angular2官方已经发布了RC 6,angular-router模块发布了RC 2.这次更新主要就是把废除的属性进行了移除跟代码重构,跟RC5相比并没有太大的变化,所以今天我们依旧用RC5来讲解,稍后我会统一把代码升级到RC 6.
Angular的主打就是单页应用(SPA),而且当我们的应用打成一个文件后体积在可承受范围之内时,我们并不需要做懒加载,这对一些中小型应用来说也是最佳选择,毕竟只需要一次加载就可以享受native的体验还是很高大上的。然而,当我们构建大型应用的时候,不得不考虑加载速度的问题,这个时候如果我们可以把某些可以拆分的模块单独打包,只有需要的时候再去加载,Lazy loading就显得格外重要了。
今天我们简单的讲一下在angular 2中怎么来做Lazy Loading,希望可以给大家一些启发或者帮助。
目录变化
老规矩我们先来看看这次跟上次的演示相比([Angular2] 添加Angular 2 router(路由)配置信息)我们项目的目录变动情况
这次的变化主要是我们把about封装成了模块(module),并且新建了一个叫blog的模块。细看名字还不一样,about文件夹前面有个+号??这代表这个模块是Lazy Loading的~哈哈~我们这里引入blog模块就是为了让大家跟好的看到lazy loading与直接加载的区别。
每个Module都单独有一个自己的routing文件,是专门负责这个模块的route的,这样就不会跟root app的routing混杂在一起了。
Blog 模块
因为blog module是在应用启动时直接下载下来的,所以我们先来看一下它吧。首先我们得 先来回顾一下我们在第二篇里([Angular2]创建简单的Angular 2 NgModule与Components)讲到关于module的理论,自行脑补下图~~
我们的Blog module就是一个简单的feature module,然后需要有自己的routing文件,大体就像下面这样:- import { NgModule } from '@angular/core';
- import { BlogComponent } from './blog.component';
- import { routing } from './blog.routing';
- @NgModule({
- imports: [routing], /** 导入我们blog module自己routing */
- declarations: [BlogComponent]/** 必须要声明这个module中要用到的component,directives,pipes */
- })
- export class BlogModule { }
- /**
- * 创建blog自己的routing文件
- */
- import { Routes, RouterModule } from '@angular/router';
- import { BlogComponent } from './blog.component';
- const routes: Routes = [
- { path: 'blog', component: BlogComponent }/** 配置blog url的导航信息*/
- ];
- export const routing = RouterModule.forChild(routes);
复制代码 然后就想上图的模型中 一样,我们需要把blog module导入到app module中
app.module.ts- import { NgModule } from '@angular/core';
- import { BrowserModule } from '@angular/platform-browser';
- import { BlogModule } from './blog/blog.module';
- import AppComponent from './common/components/app.component';
- import { HomeComponent } from './common/components/index';
- import { routing } from './common/router/app.routing';
- @NgModule({
- imports: [
- BrowserModule,
- BlogModule, /** 导入我们的Blog模块 */
- routing,
- ],
- declarations: [AppComponent, HomeComponent],
- bootstrap: [AppComponent],
- })
- export class AppModule { }
复制代码 这时候你会发现app的routing文件中并没有blog模块的链接信息??这是因为我们上面在blog模块自己routing文件中已经配置过了,而我们又把blog模块引入了app module, 所以当我们的应用启动时,不仅直接下载了blog模块的代码,blog模块的导航信息也会合并到app的主配置信息里,这样我们的应用就知道当我们点击blog按钮是应该显示哪个模块了~~
+About 模块
这里我们把之前写好的about component分离出来封装成了module,并且我们用它来演示Lazy Loading的过程。
跟Blog模块一样我们先来看一下about module的代码:- import { RouterModule, Routes } from '@angular/router';
- import { HomeComponent } from '../components/index';
- const routes: Routes = [
- { path: '', component: HomeComponent },
- { path: 'about', loadChildren: 'app/+about/about.module' } /** loadChildren??这是什么鬼?? */
- ];
- export const routing = RouterModule.forRoot(routes);
复制代码 看完这段代码发现其实跟Blog模块没啥区别啊??是的,没有错,确实没什么区别,除了!!我们的routing信息写了一个空的path,而不是about,为什么呢?这是因为我们上面的app.routing.ts中已经定义了about了啊,也就是这一行- { path: 'about', loadChildren: 'app/+about/about.module' }
复制代码 loadChilden又是神马??这就是lazy loading的关键所在了~loadChildren底层是调用了NgModuleFactoryLoader的load()方法来做的,但是这只是一个抽象类,并没有实现方法啊!!怎么做到lazy loading的!!!少年,淡定~~
如果你去查过官方的API文档你会发现,其实它还有另一个类叫SystemJsNgModuleLoader, 这又是个神马,点进去看看,原来这就是NgModuleFactoryLoader的实现类!那为什么叫SystemJsNgModuleLoader呢,难道跟systemJS有关??少年,你知道的太多了,哈哈~~没错,它的底层就是用的systemJS去加载的loadChildren中我们所写的路径,就跟我们在第一篇中配置的sysytem的信息去加载angular2的包一样一样的~~是不是瞬间觉得其实Lazy Loading看上去高大上,其实很简单的啊~~~哈哈哈
需要注意的就是,这里的loadChildren其实不止是string类型,还可以是function或者type类型。这里就留给大家自己去探索吧。
结语这里我们只是介绍了一下普通的module与Lazy Loading module在实际应用中的简单使用,并没有深入写很多复杂的route之类。因为Router其实是很大的一块,这也是问什么它在angular 2中是单独的一个模块,如果有机会的话,我会写一篇专门关于复杂router以及auth相关的文章。
最后,老规矩~~看一下我们的战利品~~
当我们点击About的时候,我们才去加载了跟About有关的代码:
文章中的代码已经整理上传到GitHub: https://github.com/WuKongW/Angular2_POC
|