面试题答案
一键面试预加载策略
- 适用场景:
- 当应用中有一些模块虽然不是在初始加载时就需要,但在用户后续操作中很可能会频繁使用时,适合使用预加载策略。例如,电商应用中用户查看订单详情、个人设置等模块,虽然不是首页加载就必需,但用户经常会访问。
- 实现方式:
- 默认预加载策略:Angular提供了
PreloadAllModules
预加载策略,它会在应用初始化完成后,自动预加载所有可以懒加载的模块。在app - routing.module.ts
中配置如下:
- 默认预加载策略:Angular提供了
import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';
const routes: Routes = [
// 路由配置
];
@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
exports: [RouterModule]
})
export class AppRoutingModule { }
- 自定义预加载策略:如果想更精细地控制哪些模块预加载,可以自定义预加载策略。首先创建一个实现
PreloadingStrategy
接口的类。例如:
import { Injectable } from '@angular/core';
import { PreloadingStrategy, Route } from '@angular/router';
import { Observable, of } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class CustomPreloadingStrategy implements PreloadingStrategy {
preload(route: Route, load: () => Observable<any>): Observable<any> {
// 根据route.data中的自定义标志判断是否预加载
if (route.data && route.data['preload']) {
return load();
} else {
return of(null);
}
}
}
然后在app - routing.module.ts
中使用自定义策略:
import { NgModule } from '@angular/core';
import { RouterModule, Routes, PreloadAllModules } from '@angular/router';
import { CustomPreloadingStrategy } from './custom - preloading - strategy';
const routes: Routes = [
{
path: 'feature - module',
loadChildren: () => import('./feature - module/feature - module.module').then(m => m.FeatureModule),
data: { preload: true }
},
// 其他路由配置
];
@NgModule({
imports: [RouterModule.forRoot(routes, { preloadingStrategy: CustomPreloadingStrategy })],
exports: [RouterModule]
})
export class AppRoutingModule { }
代码分割
- 适用场景:
- 当应用的JavaScript包体积较大时,通过代码分割可以将代码拆分成更小的块,按需加载。比如一个大型的企业级应用,有多个复杂的功能模块,将这些模块进行代码分割,只有在用户需要使用时才加载对应的代码块,从而提高初始加载性能。
- 实现方式:
- 使用路由懒加载实现代码分割:在Angular中,路由懒加载本身就是一种代码分割方式。通过
loadChildren
属性来指定懒加载模块。例如:
- 使用路由懒加载实现代码分割:在Angular中,路由懒加载本身就是一种代码分割方式。通过
const routes: Routes = [
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
},
{
path: 'user',
loadChildren: () => import('./user/user.module').then(m => m.UserModule)
}
];
- 使用Webpack的动态导入实现代码分割:在组件中也可以使用动态导入进行代码分割。例如,在一个组件中,只有在用户点击某个按钮时才加载特定的功能代码:
import { Component } from '@angular/core';
@Component({
selector: 'app - my - component',
templateUrl: './my - component.html'
})
export class MyComponent {
async loadFeature() {
const { FeatureFunction } = await import('./feature - function');
FeatureFunction();
}
}
在模板my - component.html
中:
<button (click)="loadFeature()">Load Feature</button>
这样,feature - function
的代码会在按钮点击时才加载,而不是在组件初始化时加载。