Angular 性能優化實戰
Angular 是一個非常強大的前端框架,但是如果不注意性能優化,應用程序可能會變得非常慢并增加加載時間。
以下是一些Angular性能優化經驗的實戰建議:
1. 使用 OnPush 變更檢測策略
默認情況下,Angular檢查應用程序中發生的所有數據更改,從而導致性能下降。為了解決這個問題,可以使用OnPush變更檢測策略,這將只在輸入綁定值發生更改時才啟動變更檢測。這個策略只適用于具有@Input() properties的組件,并且需要手動設置。
import {Component, ChangeDetectionStrategy} from '@angular/core';@Component({selector: 'app-sample-component',templateUrl: './sample.component.html',styleUrls: ['./sample.component.scss'],changeDetection: ChangeDetectionStrategy.OnPush
})
export class SampleComponent {// ...
}
定義一個組件并設置 changeDetection
選項為 OnPush
,如上所述。
2. 使用輕量級的管道
Angular中的管道可以用來轉換數據,并在模板中顯示不同的輸出。使用輕量級的管道可以提高Angular應用的性能。
一個經典的例子是將日期格式化為特定的字符串形式。我們可以使用內置的DatePipe管道來實現這一點,但是它可能會導致性能問題。相反,我們可以編寫一個自定義的輕量級管道來執行相同的任務:
import { Pipe, PipeTransform } from '@angular/core';@Pipe({name: 'customDate'
})
export class CustomDatePipe implements PipeTransform {transform(value: any): string {const date = new Date(value);return `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`;}
}
在模板中使用這個自定義管道:
<p>{{ myDate | customDate }}</p>
在 Angular 中使用管道來轉換數據是很方便的,但是需要注意的是,某些管道可能會對性能產生負面影響。建議遵循以下規則使用輕量級的管道:
- 盡可能使用純管道: 純管道指輸入不變時,輸出永遠不變的管道,它們只在輸入發生變化時進行計算,在模板中綁定的表達式將不會多次被執行。
- 避免使用復雜管道: 復雜管道需要更多的計算資源,因此應該盡可能避免使用它們。當您必須使用復雜管道時,應該將其結果緩存起來,以便在需要時可以重用它們。
import {Pipe, PipeTransform} from '@angular/core';@Pipe({name: 'uppercase'})
export class UpperCasePipe implements PipeTransform {transform(value: string): string {return value.toUpperCase();}
}
這樣做的好處是這個自定義管道沒有過多的附加操作或計算,因此它比內置的DatePipe稍微快一些,從而提高了整個應用程序的性能。
3. 使用懶加載模塊
在 Angular 中,懶加載模塊可以幫助你分割應用程序并提高加載時間。使用懶加載模塊可以將某些代碼推遲到用戶需要時才加載。
為了使模塊成為懶加載模塊,你需要在路由中使用 loadChildren
而不是 component
屬性。
const routes: Routes = [{path: 'lazy',loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)}
];
4. 使用 trackBy 幫助 ngFor 優化
當使用 ngFor 循環渲染數組或列表時,如果數據發生變化,“臟檢查”機制會觸發重新渲染所有列表項。
通過使用 trackBy
函數,可以告訴 Angular 如何跟蹤列表項的變化,從而避免不必要的渲染。
<ul><li *ngFor="let item of items; trackBy: itemTrackByFn">{{ item }}</li>
</ul>
itemTrackByFn(index, item) {return item.id;
}
5. 避免在引用類型中改變對象的屬性
在 Angular 應用程序中,通過在組件和服務之間傳遞引用類型,可以輕松地共享數據。
但是,如果你試圖修改已經在其他地方使用的對象的屬性,則所有對該對象的引用都將受到影響,這可能導致不必要的變更檢測。
為了避免這種情況,盡量避免直接修改對象的屬性,而是使用 Object.assign()
或 spread
運算符創建新對象。
const user = { id: 1, name: 'John Doe', email: 'john@example.com' };// 不好的寫法
this.userService.updateUser(user.id, user.name);
user.email = 'new-email@example.com';// 好的寫法
this.userService.updateUser(user.id, user.name, { email: 'new-email@example.com' });
6. 使用虛擬滾動
當你需要處理大量數據時,虛擬滾動可以幫助你實現快速、流暢的滾動體驗,而無需渲染整個列表。
Angular CDK 提供了一個名為 CdkVirtualScrollViewport
的指令,它可以幫助你實現虛擬滾動。
<cdk-virtual-scroll-viewport itemSize="50" class="example-viewport"><div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div>
</cdk-virtual-scroll-viewport>
以上是一些 Angular 性能優化的實戰,其中一些技術可以單獨應用,同時使用全部技巧可以幫助你最大程度地提高 Angular 應用程序的性能并改善用戶體驗。
7. 開啟 AOT 編譯
開啟 AOT 編譯可以大大提高應用程序的性能。AOT 編譯將在構建期間對組件/指令和模板進行編譯,并將生成的 JavaScript 代碼直接注入到 HTML 模板中。這意味著在運行時,瀏覽器不再需要編譯模板,從而減少啟動時間和加載時間。
具體來說,以下是如何開啟 AOT 編譯:
- 在 Angular CLI 中使用
--aot
選項構建您的應用程序:ng build --aot
- 在 Angular 應用程序中配置 JIT 編譯器,以便像 AOT 所做的那樣提前編譯組件:
@NgModule({// ...providers: [{provide: COMPILER_OPTIONS,useValue: {providers: [{useClass: JitCompiler}]},multi: true}],// ...
})
export class AppModule {}
以上是一些 Angular 性能優化的實戰,其中一些技術可以單獨應用,也可以同時使用,它可以幫助你最大程度地提高 Angular 應用程序的性能并改善用戶體驗。