angular5懒加载之模块划分
很多人在项目前期时用得很流畅,但随着项目变得复杂庞大以后,就会出现首页加载慢的问题。这是因为把所有页面都放在一个模块里,而首页载入其实就是把整个项目加载进来了,因此会觉得的越来越慢。所以,我们需要根据项目业务情况来划分不同的功能模块,按需加载模块,来提升用户体验。
下面我根据我所做的项目情况来分享一下进行模块划分的过程,由于我所做的项目模块比较多,所以我做了个简化版的demo,以便截图和讲解。
我的项目目录结构如下:
主要包括(登录、注册、首页、用户管理),其中登录、注册、首页这3个页面公用头部和尾部的组件。页面布局结构如下:
下面是app.module.ts文件的主要代码:
下面是app-routing.module.ts文件的主要代码:
根据业务的发展来看,用户管理后期是会持续迭代功能的,首页跟登录页用户使用的概论比较高,注册页面的使用率相对小且改动的概论也小。由此,我把注册和用户管理划分为2个特性模块,首页跟登录页留着主模块中。
1. 划分用户管理模块
在app文件中,新建一个load-module的文件夹,然后在里面创建用户管理模块的路由配置模块customers-routing.module,代码如下:
这里需要注意,我使用了RouterModule.forChild()而不是RouterModule.forRoot()。RouterModule对象提供了两个静态的方法:forRoot()和forChild()来配置路由信息。
RouterModule.forRoot()方法用于在主模块中定义主要的路由信息,RouterModule.forChild()与 Router.forRoot()方法类似,但它只能应用在特性模块中。即根模块中使用forRoot(),子模块中使用forChild()。
在load-module的文件中,创建用户管理模块的声明模块customers.module,把用户管理模块所用的到的指令/管道/组件的声明都迁移过来,代码如下:
这里需要注意的是,引入了一个CommonModule模块,CommonModule提供了很多应用程序中常用的指令,包括NgIf和NgFor等。更准确地说,NgIf等指令是来自@angular/common的CommonModule中声明的。
我们在根模块AppModule中导入了BrowserModule模块,BrowserModule导入了CommonModule并且重新导出了它。最终的效果是:只要导入BrowserModule就自动获得了CommonModule中的指令。
导入BrowserModule会让该模块公开的所有组件、指令和管道在AppModule下的任何组件模板中直接可用,而不需要额外的繁琐步骤。但是在其它任何模块中都不要导入BrowserModule。特性模块和惰性加载模块应该改成导入CommonModule。它们不需要重新初始化全应用级的提供商。 如果你在惰性加载模块中导入BrowserModule,Angular就会抛出一个错误:大概的提示是BrowserModule模块已经下载了,如果想使用ng自带的指令/管道,引入CommonModule。
1.1 划分管道共享模块
由于考虑到用户模块后期变得更复杂,可能会根据情况再划分子模块,而里面用的的管道可能会被多个子模块使用到,所以把管道分离出来做一个共享模块以备以后的多个子模块公用。
看到这里,可能有些人会有个疑惑:什么时候该分离共享模块?当一个组件/指令/管道,被多个模块使用到的时候,就应该分离到共享模块中,然后在各个子模块中引入这个共享模块。在ng5中,如果要在模块中使用一个组件/指令/管道,必须要做声明,而且只能在一个模块中声明。因此我们需要在共享模块中声明公用的组件/指令/管道,导出给别的模块使用。想了解更多关于共享模块的知识,请点击 传送门 。
在load-module的文件中,创建管道共享模块share -pipe.module,把管道的声明迁移过来,代码如下:
在用户管理模块的声明模块customers.module中引入共享模块share -pipe.module,代码如下:
1.2 修改根模块路由
在根模块路由AppRoutingModule中配置用户管理模块CustomersModule的路由信息,代码如下:
这里使用到了懒加载LoadChildren属性。这里没有将CustomersModule导入到AppModule中,而是通过loadChildren属性,告诉Angular路由依据loadChildren属性配置的路径去加载CustomersModule模块。这就是模块懒加载功能的具体应用,当用户访问 /customers/** 路径的时候,才会加载对应的CustomersModule模块,这减少了应用启动时加载资源的大小。
我们再看看现在的根模块的声明模块在迁移了用户模块之后怎么样了,代码如下:
把用户模块这个大块头划分出去之后,首页加载速度明显变快了,接下来我们继续划分注册模板吧。
2. 划分注册模块管理模块
在load-module的文件中,创建注册模块的路由配置模块regist-routing.module,代码如下:
注册模块主要用到3个组件:regist、head、foot,其中head、foot会被主模块中的首页和登录页用到,所以需要把这head、foot两个组件分离到一个共享模块。
在load-module的文件中,创建组件共享模块share-component.module,把组件的声明迁移过来,代码如下:
在load-module的文件中,创建注册模块regist.module,把组件的声明迁移过来,并且引入共享组件模块ShareComponentModule,代码如下:
在根模块路由AppRoutingModule中配置用户管理模块RegistModule的路由信息,代码如下:
最后我们看看根模块的声明模块迁移了用户模块之后怎么样了,代码如下:
到此,我们这一次划分模块的任务就完成了,后期的话还可以进一步优化,比如懒加载模块过大,加载过程有段卡顿时间,这里可以用ng5的动画做过度提升用户体验。另外,可以根据需要把按需加载改成预加载,后续有空再补充预加载的内容。