Performance
Nima bu?
Pure pipe Angular ichida stateful cache saqlaydi: oldingi input(lar) va natija. Keyingi CD'da input bir xil bo'lsa (primitive taqqoslash yoki reference equality) transform() qayta chaqirilmaydi — natija cache'dan qaytariladi. Bu O(1) tezlik beradi, lekin faqat pure pipe'larda ishlaydi.
Kod misoli
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'expensiveCalc',
standalone: true,
pure: true,
})
export class ExpensiveCalcPipe implements PipeTransform {
transform(items: number[]): number {
console.log('expensiveCalc transform chaqirildi');
// Og'ir hisob (misol uchun)
return items.reduce((acc, n) => acc + Math.sqrt(n) * 1000, 0);
}
}
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { ExpensiveCalcPipe } from './expensive-calc.pipe';
@Component({
selector: 'app-calc-demo',
standalone: true,
imports: [ExpensiveCalcPipe],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<p>Natija: {{ data | expensiveCalc }}</p>
<p>Boshqa: {{ unrelatedCounter }}</p>
<button type="button" (click)="bumpCounter()">Counter +1</button>
<button type="button" (click)="newData()">Yangi data</button>
`,
})
export class CalcDemoComponent {
data = [1, 4, 9, 16, 25];
unrelatedCounter = 0;
bumpCounter(): void {
this.unrelatedCounter++; // pure pipe qayta ishlamaydi — cache
}
newData(): void {
this.data = [...this.data, 36]; // yangi reference — transform qayta chaqiriladi
}
}
Imtihonda
- Pure pipe cache qaysi asosda ishlaydi?
- Bir template'da
{{ x | pipe }}ikki marta — necha marta transform? - Pipe ichida side effect bo'lsa nima bo'ladi?
Yodlash uchun
Pure pipe = input equality → cache; side effect qo'yma.
Nima bu?
Katta ro'yxatda (1000+ element) template pipe har element uchun alohida ishlashi mumkin. Computed signal, getter yoki komponent metodi bilan bir marta hisoblab, natijani cache qilish samaraliroq. Pipe kichik transform uchun, og'ir filter/sort komponentda.
Kod misoli
import { Component, computed, signal } from '@angular/core';
interface Product {
id: number;
name: string;
category: string;
price: number;
}
@Component({
selector: 'app-product-catalog',
standalone: true,
template: `
<input [value]="searchTerm()" (input)="onSearch($event)" placeholder="Qidirish..." />
<p>{{ filteredProducts().length }} ta mahsulot</p>
<ul>
@for (p of filteredProducts(); track p.id) {
<li>{{ p.name }} — {{ p.price | number:'1.0-0' }} so'm</li>
}
</ul>
`,
})
export class ProductCatalogComponent {
products = signal<Product[]>(
Array.from({ length: 5000 }, (_, i) => ({
id: i,
name: `Mahsulot ${i}`,
category: i % 3 === 0 ? 'phone' : 'laptop',
price: 1_000_000 + i * 10_000,
}))
);
searchTerm = signal('');
categoryFilter = signal<string | null>(null);
filteredProducts = computed(() => {
const term = this.searchTerm().toLowerCase();
const cat = this.categoryFilter();
return this.products().filter(p => {
const matchTerm = !term || p.name.toLowerCase().includes(term);
const matchCat = !cat || p.category === cat;
return matchTerm && matchCat;
});
});
onSearch(event: Event): void {
this.searchTerm.set((event.target as HTMLInputElement).value);
}
}
Imtihonda
- Pipe vs computed — qachon qaysi biri?
*ngForichida pipe performance ta'siri?- Virtual scroll bilan birga qanday optimizatsiya?
Yodlash uchun
Katta data = computed/signal; pipe = oddiy format; filter komponentda.
Nima bu?
Impure pipe har change detection'da, har bir binding joyida transform() ni chaqiradi. Katta komponent daraxtida va ko'p elementli *ngFor da bu O(n × CD tsikllar) yuk hosil qiladi. UI sekinlashadi, batareya sarflanadi. DevTools Performance tab'da ko'p pipe chaqiruvlari ko'rinadi.
Kod misoli
import { Pipe, PipeTransform, Component } from '@angular/core';
@Pipe({ name: 'sortByName', standalone: true, pure: false })
export class SortByNamePipe implements PipeTransform {
transform<T extends { name: string }>(items: T[]): T[] {
// Har CD'da sort — qimmat!
return [...items].sort((a, b) => a.name.localeCompare(b.name));
}
}
@Component({
selector: 'app-bad-example',
standalone: true,
imports: [SortByNamePipe],
template: `
<!-- 1000 element × har CD = juda sekin -->
@for (user of users | sortByName; track user.id) {
<span>{{ user.name }}</span>
}
<button type="button" (click)="tick()">Har qanday click CD trigger</button>
`,
})
export class BadExampleComponent {
users = Array.from({ length: 1000 }, (_, i) => ({
id: i,
name: `User ${999 - i}`,
}));
tick(): void {
// hech narsa o'zgarmaydi, lekin impure pipe qayta sort qiladi
}
}
// Yaxshi yechim: computed yoki sort faqat data o'zgarganda
import { computed, signal } from '@angular/core';
sortedUsers = computed(() =>
[...this.users()].sort((a, b) => a.name.localeCompare(b.name))
);
Imtihonda
- Impure pipe + *ngFor = qanday murakkablik?
- DevTools'da qanday aniqlash?
- Impure pipe qabul qilinadigan edge case?
Yodlash uchun
Impure + katta list = performance bomba; computed/sort on change ishlat.
