如何利用管道提高Angular應用程序的性能?本篇文章通過代碼示例來給大家詳細介紹一下利用管道提高Angular應用程序性能的方法。
我們通過一個例子來演示下:
Example
@Component({ selector: 'my-app', template: ` <p *ngFor="let user of users"> {{ user.name }}有一只貓 {{ getCat(user.id).name }} </p> `, styleUrls: ['./app.component.css'] }) export class AppComponent { users = [{ id: 1, name: 'wang' }, { id: 2, name: 'li' }]; cats = [{ name: 'Tom', userId: 1 }, { name: 'Jerry', userId: 2 }]; getCat(userId: number) { console.log('User', userId); return this.cats.find(c => c.userId === userId); } }
有兩組數據分別是 users
與 cats
,可以把 users
理解為傳入數據,或者是其他數據源。通過 getCat()
方法獲取對應的 貓咪,這種場景再業務開發中再熟悉不過。 最后添加全局模板直接進行一個循環輸出?!鞠嚓P教程推薦:《angular教程》】
接下來看下輸出
User 1 User 2 User 1 User 2 User 1 User 2 User 1 User 2
可以 getCat()
方法調用了 8 次,有 6 次無用調用。這是因為當在模板內使用方法時,angular
每次變更檢測都會調用其方法。
我們可以添加一個監聽事件
@HostListener('click') clicked() { }
每當點擊事件觸發,就會調用 4 次
User 1 User 2 User 1 User 2
這不是我想要,我只想讓它調用兩次啊!?。祿看罅诉@么玩頂不住。
Pure Pipe
接下來就是主角登場了。我們先創建一個 pipe
@Pipe({ name: 'cat', }) export class CatPipe implements PipeTransform { constructor(private appComponent: AppComponent) {} transform(value, property: 'name' | 'userId'): unknown { console.log('User', value); const cat = this.appComponent.cats.find(c => c.userId === value); if (cat) { return cat[property]; } } }
可以看到 pipe
的實現與之前調用的方法基本是一樣的,在模板中添加引用之后,卻發現結果符合之前的預期了,只調用了兩次。
這是因為 pipe
默認是 pure pipe
,且 Pipe
裝飾器有 pure
可用來設置管道模式。
@Pipe({ name: 'cat', pure: true })
而 pure
表示的是: transform
的值(入參value)發生變化時是否 不跟隨變更檢測調用。
官方解釋:如果該管道具有內部狀態(也就是說,其結果會依賴內部狀態,而不僅僅依賴參數),就要把 pure 設置為 false。 這種情況下,該管道會在每個變更檢測周期中都被調用一次 —— 即使其參數沒有發生任何變化。 When true, the pipe is pure, meaning that the transform() method is invoked only when its input arguments change. Pipes are pure by default.
當把 pure
改成 false
,會隨變更檢測調用多次,不管值發生變化沒。
了解變更檢測機制:
[譯]深入理解Angular onPush變更檢測策略
https://zhuanlan.zhihu.com/p/96486260
這樣我們通過 pipe
代替模板中的方法,就減少了 angular
模板中不必要的調用。
總結
當模板中數據為靜態數據需要轉換或加工時,調用pipe比調用方法好。