最近運行項目的時候發現項目加載過慢,因為項目需求一直在疊加,一直沒找到一個好的時機去優化它,導致在app.module中的import一直在累加,主要解決的就是vendor和main這兩個大文件。參考了網上很多大神的優化和angular官方的一些文檔,有了一些自己的優化辦法。
一、懶加載
要惰性加载 Angular 模块,需要在 app-routing.module.ts
中使用 loadChildren
代替 component
进行配置,例:
const ROUTES:Routes = [
{path:'',redirectTo:'login',pathMatch:'full'},
{path:'login',component:LoginPageComponent},
{path:'main',component:MainPageComponent, children:mainPart,canActivate: [LoginGuard]},
]
const mainPart:any = [
{path:'',redirectTo:'datamanagement',pathMatch:'full'},
//{path:'datamanagement',component:DataManagementPageComponent} 改造前未增加懶加載
{path:'datamanagement',loadChildren: () => import('./pages/data-management-page/data- management-page.module').then(m => m.DataManagementPageModule)},//改造後
]
以上述dataManagementPage為例,作為一個單獨的頁面,需要在跳轉的時候載入它所需要的模塊及一些必要的声明组件、指令和管道等等,這就讓這個路由所需要的模塊不會在初始加載的時候就開始導入這些包。
注意,惰性加载语法使用 loadChildren
,其后是一个使用浏览器内置的 import('...')
语法进行动态导入的函数。 其导入路径是到当前模块的相对路径。
基于字符串的惰性加载
在 Angular 版本 8 中,
loadChildren
路由规范的字符串语法已弃用,建议改用import()
语法。不过,你仍然可以通过在tsconfig
文件中包含惰性加载的路由来选择使用基于字符串的惰性加载(loadChildren: './path/to/module#Module'
),这样它就会在编译时包含惰性加载的文件。
1.创建一个带路由的特性模块(dataManagementPage)
快捷指令:ng g module data-management-page --route data-management-page --module app.module
這一步是為了建立一個特性模塊,這個模塊包含一個component必要的一些文件(html,css,spec,ts,以及可惰性加载模块data-management-page.module.ts和其桩组件data-management-page-routing.module.ts)
(1).data-management-page.module.ts
import { NgModule} from '@angular/core';
import { CommonModule } from '@angular/common';
import { DataManagementPageComponent } from './data-management-page.component';
import { DataManagementPageRoutingModule } from './data-management-page-routing.module';
import { NzTableModule } from 'ng-zorro-antd/table';
import { NzTabsModule } from 'ng-zorro-antd/tabs';
@NgModule({
declarations: [DataManagementPageComponent],
imports: [
CommonModule,
DataManagementPageRoutingModule,
NzTableModule,
NzTabsModule
]
})
export class DataManagementPageModule { }
這個文件中定义了新的可惰性加载模块 dataManagementPageModule。该命令会自动在新特性模块中声明 dataManagementPage。因为这个新模块想要惰性加载,所以该命令不会在应用的根模块 app.module.ts
中添加对新特性模块的引用。 相反,它将声明的路由 datamanagement添加到以 --module
选项指定的模块中声明的 routes
数组中。
data-management-page.module.ts 文件导入了 data-management-page.module.ts和 data-management-page.component.ts 文件。@ngModule的 imports
数组中列出了 dataManagementPageRoutingModule,让 dataManagementPageModule可以访问它自己的路由模块。dataManagementPageComponent位于 declarations
数组中,这意味着 dataManagementPageComponent 属于 dataManagementPageModule。
然后,app-routing.module.ts
会使用 JavaScript 的动态导入功能来导入特性模块 data-management-page.module.ts。
专属于特性模块的路由定义文件 data-management-page.module.ts 将导入在 data-management-page.component.ts文件中定义的自有特性组件,以及其它 JavaScript 导入语句。然后将空路径映射到 dataManagementPageComponent。
(2).data-management-page-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DataManagementPageComponent } from './data-management-page.component';
const routes: Routes = [{ path: '', component: DataManagementPageComponent }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class DataManagementPageRoutingModule { }
这里的 path
设置为空字符串,因为 AppRoutingModule
中的路径已经设置为 datamanagement,因此,DataManagementPageRoutingModule中的此路由已经位于 datamanagement 这个上下文中。此路由模块中的每个路由都是其子路由。到這裡整個component的懶加載就結束了。
在優化的時候有遇到以下的問題,遇到的時候可以參考一下。
注意點:
1.因為有些模塊是之前就建立完的並沒有module這些模塊,所以裡面的一些導包需要自己去加上
例:
這是因為我有在datamanagement這個模塊裡面有加入confirm這個共用模塊,但是我沒有在data-management-page.module.ts這個文件中的import中加入這個模塊
加入以下代碼就可以解決
import { ConfirmComponent } from 'src/app/components/confirm/confirm.component';
declarations: [
BasicinfomgComponent,
ConfirmComponent
],
2.因為我有用到外部的一些組件庫的東西,例NG-ZORRO
這是缺少導入的nztable組件
加入以下代碼
import { NzTableModule } from 'ng-zorro-antd/table';
imports: [
CommonModule,
DataManagementPageRoutingModule,
NzTableModule,
NzTabsModule
]
另外的一個特殊一點的
當時以為是input沒有引入進來,加入input組件後試了幾遍後發現還是依舊報錯,然後查閱了一些資料後,是需要加入formsModule
import { FormsModule } from '@angular/forms';
imports: [
CommonModule,
BasicinfomgRoutingModule,
FormsModule
]
加入之後就解決上述問題了,其他的基本上都是這種問題。
3.要注意在你的路由模塊內部引用的那些部分,不可以在app.module.ts中導入
參考: