Angular Ivy是Angular 9及更高版本中引入的默认渲染引擎,它取代了以前的View Engine。Ivy的目标是提高Angular的性能、减少包大小和提高开发者的生产力。
1. AOT编译的改进:
在Ivy中,Angular使用了更早的AOT(Ahead-of-Time)编译,这意味着在构建时就将模板转换为纯JavaScript,减少了运行时的编译开销。在旧的View Engine中,AOT编译会产生多个大的元数据文件,而在Ivy中,这些元数据被直接内联在组件类中,减少了加载时间。
2. 更小的输出大小:
Ivy生成的代码更小,因为它的元数据格式更紧凑,而且它支持懒加载模块的更细粒度的拆分。这意味着用户只需下载他们实际使用的代码,而不是整个应用。
3. 更快的启动时间:
由于Ivy的元数据结构和更有效的编译过程,应用启动更快。Ivy使用了新的元数据格式,减少了解析和初始化的时间。
4. 更好的类型检查和错误报告:
Ivy在构建时提供了更好的类型检查,这意味着在编译阶段就能捕获更多错误,而不是在运行时。这提高了开发效率并减少了潜在的运行时问题。
5. 更容易的库开发:
Ivy允许库作者直接在他们的库中使用Ivy编译,无需额外的配置。这简化了库的创建和维护,同时也使库的使用者受益。
6. 动态组件的优化:
Ivy对动态组件的支持也进行了优化,降低了动态组件创建和销毁的开销,这对于频繁创建和销毁组件的应用来说是一个显著的性能提升。
7. 更强的DI(依赖注入):
Ivy的依赖注入系统更加高效,减少了查找依赖的开销,尤其是在大型应用中。
8. 更好的树摇优化:
Tree-shaking是现代JavaScript打包工具的一个特性,用于删除未使用的代码。Ivy的设计使得tree-shaking更容易和有效,进一步减小了最终的包大小。
要启用Ivy,你通常不需要在Angular 9及更高版本中做任何特殊配置,因为它已经是默认选项。然而,如果你需要手动启用或禁用,可以在angular.json
配置文件中设置"enableIvy"为true或false。
代码示例(在Angular 9+的tsconfig.app.json文件中):
{
"compilerOptions": {
"enableIvy": true
}
}
9. 模块与指令的局部作用域
Ivy 引入了模块和指令的局部作用域概念,这意味着组件可以声明自己的局部指令或管道,而不会污染全局命名空间。这不仅减少了全局范围的潜在冲突,还使得代码组织更加清晰,便于维护。
10. 改进的变更检测
Ivy 对变更检测机制进行了优化,能够更精准地追踪哪些组件需要被检查更新。它引入了“增量构建器”(Incremental DOM Builder),该机制在构建DOM时,仅更新那些数据确实发生变化的部分,从而减少了不必要的DOM操作,提升了性能。
11. 持续的性能优化
Angular团队持续对Ivy进行优化,比如通过减少运行时代码量、改进数据绑定机制等方式,进一步提升应用的启动速度和运行时性能。
让我们看一个简单的Angular组件例子,展示如何利用Ivy的特性:
// app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
{{ title }}
<button (click)="changeTitle()">Change Title</button>
`,
styles: []
})
export class AppComponent {
title = 'Angular Ivy App';
changeTitle() {
this.title = 'New Title';
}
}
在上面代码中,Ivy会通过AOT编译将模板转换为高效的JavaScript代码,减少运行时解析负担。同时,变更检测机制会精确监控title属性的变化,仅当点击按钮触发changeTitle()方法,修改了title的值时,才会触发视图的更新。
12. Tree-shakable服务与依赖
在Ivy中,服务也可以被tree-shake,意味着如果你的应用没有使用某个服务,那么这个服务相关的代码就不会被打包进最终的产物中。这通过在服务提供者上使用@Injectable({ providedIn: 'root' })装饰器实现,它指示Angular在根模块中提供此服务,同时允许tree-shaker识别未被引用的服务。
13. 懒加载与预加载策略
Ivy 支持更精细的懒加载和预加载策略,这在大型应用中尤为重要。懒加载允许应用按需加载模块,即只有当用户导航到特定路由时,相关的模块才会被加载进来,这有助于减少初始加载时间。预加载则是在后台预先加载可能即将用到的模块,以提升用户体验。
在Angular中,通过Angular Router配置懒加载非常简单:
// app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutModule } from './about/about.module'; // 假设AboutModule是一个懒加载模块
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', loadChildren: () => import('./about/about.module').then(m => m.AboutModule) }, // 懒加载关于页面模块
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
预加载策略可以在Angular Router的配置中通过preloadingStrategy选项指定,使用PreloadAllModules策略可以自动预加载所有懒加载模块:
// main.ts 或 app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, PreloadAllModules } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
RouterModule.forRoot(AppRoutingModule.routes, { preloadingStrategy: PreloadAllModules }) // 预加载所有模块
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
14. Angular Elements
Ivy 支持Angular Elements,这是一种将Angular组件包装为Web Components的技术,使得Angular组件可以在任何支持Web Components标准的平台上运行,包括非Angular应用。这极大地增强了组件的可复用性和跨框架兼容性。
15. 性能监控与诊断
Angular提供了强大的开发者工具,如Angular DevTools,它可以帮助开发者深入了解应用的变更检测、内存分配、渲染性能等,这对于诊断和优化应用性能至关重要。Ivy的改进使得这些工具能够提供更准确和详细的性能数据。
16. 国际化(i18n)与本地化
Ivy对国际化(Internationalization, i18n)的支持也有所增强,提供了更灵活的标记和提取机制,使得多语言应用的开发和维护更加高效。开发者可以使用ng xi18n命令来提取翻译标签,并使用相应的工具或服务来完成翻译。