IslomDevIslomDev
Booster
Imtihon
Booster
Imtihon
  • Angular Intervyu Tayyorgarlik
  • JavaScript / TypeScript

    • JavaScript / TypeScript
    • Asoslar (JavaScript)
    • Asinxronlik
    • Prototip va OOP
    • TypeScript
    • Performance
  • Algoritmlash

    • Algoritmlash
    • Murakkablik tahlili
    • Ma'lumot tuzilmalari
    • Qidiruv va Saralash
    • Algoritmik paradigmalar
    • Amaliy masalalar
  • Angular — Boshlang'ich

    • Angular — Boshlang'ich
    • Component
    • Template
    • Change Detection
    • Advanced Component
  • Angular — Service va DI

    • Angular — Service va DI
    • Service asoslari
    • HTTP
    • Hierarchical DI
    • Advanced DI
    • State management (service)
  • Angular — Versiyalar

    • Angular — Versiyalar
    • Angular 12–13
    • Angular 14
    • Angular 15
    • Angular 16
    • Angular 17
    • Angular 18+
  • Angular — Directive

    • Angular — Directive
    • Built-in Directives
    • Custom Attribute Directive
    • Custom Structural Directive
    • Advanced
  • Angular — RxJS

    • Angular — RxJS
    • Observable asoslari
    • Asosiy operatorlar
    • Higher-order operatorlar
    • Combination operatorlar
    • Subject turlari
    • Xato va xotira
    • Advanced
  • Angular — Pipe

    • Angular — Pipe
    • Built-in Pipes
    • Custom Pipe
    • Performance
  • Angular — Forms

    • Angular — Forms
    • Template-driven Forms
    • Reactive Forms
    • Validators
    • Advanced
  • Angular — NgModule

    • Angular — NgModule
    • NgModule asoslari
    • Module arxitekturasi
    • Lazy Loading
    • Standalone vs NgModule
  • Angular — Sintaksis va Clean Code

    • Angular — Sintaksis va Clean Code
    • Template sintaksisi
    • Angular 17+ yangi sintaksis
    • Komponent arxitekturasi
    • Performance pattern'lar
    • SOLID va Clean Code
    • Testing

Performance pattern'lar

Daraja:

Angular ilovasida performance — change detection strategiyasi, DOM qayta yaratilmasligi, pure pipe, virtual scroll va bundle optimizatsiyasi orqali erishiladi. Bu guruh intervyuda eng ko'p so'raladigan amaliy pattern'larni qamrab oladi.

OnPush + async pipe — eng tez pattern

Middle

Nima bu?

ChangeDetectionStrategy.OnPush komponentni faqat yangi @Input reference, ichki event, async pipe yangi qiymati yoki markForCheck() da tekshiradi. async pipe Observable'ni subscribe qiladi va yangi qiymat kelganda avtomatik CD trigger qiladi — manual subscribe va ChangeDetectorRef.detectChanges() kerak emas. Immutable data + OnPush — eng samarali kombinatsiya.

Kod misoli

import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { AsyncPipe } from '@angular/common';
import { Observable, map } from 'rxjs';
import { UserService } from './user.service';

interface User {
  id: number;
  name: string;
  active: boolean;
}

@Component({
  selector: 'app-user-list',
  standalone: true,
  imports: [AsyncPipe],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    @if (users$ | async; as users) {
      <ul>
        @for (user of users; track user.id) {
          <li>{{ user.name }}</li>
        }
      </ul>
    }
  `,
})
export class UserListComponent {
  private userService = inject(UserService);

  users$: Observable<User[]> = this.userService.getUsers().pipe(
    map((users) => users.filter((u) => u.active))
  );
}
// XATO — OnPush + manual mutate (CD ishlamaydi)
this.users.push(newUser); // ❌

// TO'G'RI — yangi reference
this.users = [...this.users, newUser]; // ✅
// yoki signal/update pattern

Imtihonda

  • OnPush qachon CD trigger bo'ladi?
  • async pipe unsubscribe qiladi mi?
  • OnPush bilan BehaviorSubject qanday ishlatiladi?

Yodlash uchun

OnPush + immutable data + async pipe = minimal CD.

trackBy — *ngFor DOM qayta yaratilmasin

Middle

Nima bu?

Ro'yxat yangilanganda Angular default holda index bo'yicha solishtiradi — element qo'shilsa yoki o'chirilsa ko'p DOM node qayta yaratiladi. trackBy (klassik) yoki track (Angular 17+) unique id bo'yicha mavjud node'larni qayta ishlatadi. Input focus, animation va performance saqlanadi.

Kod misoli

import { Component, signal } from '@angular/core';
import { NgFor } from '@angular/common';

interface Item {
  id: number;
  label: string;
}

@Component({
  selector: 'app-track-demo',
  standalone: true,
  template: `
    <!-- Angular 17+ — track majburiy -->
    @for (item of items(); track item.id) {
      <input [value]="item.label" />
    }

    <!-- Klassik *ngFor + trackBy -->
    <div *ngFor="let item of items(); trackBy: trackById">
      {{ item.label }}
    </div>
  `,
  imports: [NgFor],
})
export class TrackDemoComponent {
  items = signal<Item[]>([
    { id: 1, label: 'Birinchi' },
    { id: 2, label: 'Ikkinchi' },
  ]);

  trackById(_index: number, item: Item): number {
    return item.id;
  }

  prepend(): void {
    this.items.update((list) => [
      { id: Date.now(), label: 'Yangi' },
      ...list,
    ]);
  }
}

Imtihonda

  • trackBy bo'lmasa nima muammo bo'ladi?
  • track $index qachon xavfli?
  • @for ... track va *ngFor trackBy farqi?

Yodlash uchun

Unique id bilan track — DOM reuse; $index faqat statik ro'yxat.

Pure pipe — computed qiymatlar

Middle

Nima bu?

Pure pipe (default) — faqat primitive @Input yoki ob'ekt reference o'zgarganda qayta hisoblanadi. Template'da method chaqirish ({{ getTotal() }}) har CD da ishlaydi; pure pipe esa cache qiladi. impure: true har CD da ishlaydi — faqat zarurat bo'lsa. Currency, Date, Async pipe — built-in pure.

Kod misoli

import { Pipe, PipeTransform } from '@angular/core';
import { CurrencyPipe } from '@angular/common';

interface OrderLine {
  product: string;
  qty: number;
  price: number;
}

@Pipe({ name: 'orderTotal', standalone: true })
export class OrderTotalPipe implements PipeTransform {
  transform(lines: OrderLine[], taxRate = 0.12): number {
    const subtotal = lines.reduce((sum, l) => sum + l.qty * l.price, 0);
    return subtotal * (1 + taxRate);
  }
}
@Component({
  selector: 'app-order-summary',
  standalone: true,
  imports: [OrderTotalPipe, CurrencyPipe],
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <!-- Pure pipe — lines reference o'zgarganda hisoblanadi -->
    <p>Jami: {{ lines | orderTotal:0.12 | currency:'UZS' }}</p>

    <!-- ❌ Har CD da chaqiriladi -->
    <!-- <p>{{ calculateTotal() }}</p> -->
  `,
})
export class OrderSummaryComponent {
  lines: OrderLine[] = [
    { product: 'Kitob', qty: 2, price: 50_000 },
    { product: 'Daftar', qty: 1, price: 15_000 },
  ];
}

Imtihonda

  • Pure va impure pipe farqi?
  • Pipe vs getter vs computed signal qachon tanlanadi?
  • Pure pipe ob'ekt ichidagi property o'zgarsa nima bo'ladi?

Yodlash uchun

Pure pipe = reference o'zgarganda; method call = har CD.

Virtual Scrolling — CDK (katta ro'yxat)

Senior

Nima bu?

Virtual scrolling — faqat viewport'da ko'rinadigan elementlar DOM'da render qilinadi (odatda + buffer). 10 000+ qatorli ro'yxatlar uchun @angular/cdk/scrolling cdk-virtual-scroll-viewport ishlatiladi. itemSize (fixed) yoki AutosizeVirtualScrollStrategy (dynamic height) tanlanadi.

Kod misoli

import { Component } from '@angular/core';
import { ScrollingModule } from '@angular/cdk/scrolling';

interface Row {
  id: number;
  title: string;
}

@Component({
  selector: 'app-virtual-table',
  standalone: true,
  imports: [ScrollingModule],
  template: `
    <cdk-virtual-scroll-viewport itemSize="48" class="viewport">
      <div *cdkVirtualFor="let row of rows; trackBy: trackById" class="row">
        <span>{{ row.id }}</span>
        <span>{{ row.title }}</span>
      </div>
    </cdk-virtual-scroll-viewport>
  `,
  styles: [`
    .viewport { height: 400px; }
    .row { height: 48px; display: flex; gap: 1rem; align-items: center; }
  `],
})
export class VirtualTableComponent {
  rows: Row[] = Array.from({ length: 50_000 }, (_, i) => ({
    id: i + 1,
    title: `Qator #${i + 1}`,
  }));

  trackById(_: number, row: Row): number {
    return row.id;
  }
}

Imtihonda

  • Virtual scroll qachon kerak, qachon @for yetarli?
  • itemSize noto'g'ri bo'lsa nima bo'ladi?
  • CDK virtual scroll va third-party (ngx-virtual-scroller) farqi?

Yodlash uchun

Katta ro'yxat → CDK viewport; faqat ko'rinadigan item render.

Lazy loading images — loading='lazy'

JuniorMiddle

Nima bu?

Native loading="lazy" atributi — rasm viewport'ga yaqinlashganda yuklanadi. Initial page load va bandwidth tejaydi. NgOptimizedImage (@angular/common) — srcset, priority, placeholder va LCP optimizatsiyasi beradi. Above-the-fold rasmlar uchun priority ishlatiladi.

Kod misoli

import { Component } from '@angular/core';
import { NgOptimizedImage } from '@angular/common';

@Component({
  selector: 'app-gallery',
  standalone: true,
  imports: [NgOptimizedImage],
  template: `
    <!-- Hero — darhol yuklash -->
    <img ngSrc="/assets/hero.webp"
         width="1200" height="600"
         priority
         alt="Bosh sahifa" />

    <!-- Galereya — lazy -->
    @for (photo of photos; track photo.id) {
      <img [ngSrc]="photo.url"
           [width]="photo.w"
           [height]="photo.h"
           loading="lazy"
           [alt]="photo.caption" />
    }

    <!-- Oddiy HTML lazy (NgOptimizedImage'siz) -->
    <img src="/assets/thumb.jpg" loading="lazy" alt="Miniatura" />
  `,
})
export class GalleryComponent {
  photos = [
    { id: 1, url: '/assets/p1.webp', w: 400, h: 300, caption: 'Manzara' },
    { id: 2, url: '/assets/p2.webp', w: 400, h: 300, caption: 'Shahar' },
  ];
}

Imtihonda

  • loading="lazy" qaysi brauzerlarda qo'llab-quvvatlanadi?
  • NgOptimizedImage nima uchun width/height talab qiladi?
  • LCP (Largest Contentful Paint) uchun qanday optimizatsiya?

Yodlash uchun

Hero → priority; pastdagi rasmlar → loading="lazy".

Tree shaking — ko'p import qilmaslik

Senior

Nima bu?

Tree shaking — ishlatilmagan kod production bundle'dan olib tashlanadi. import * as _ from 'lodash' butun kutubxonani oladi; import { debounce } from 'lodash-es' faqat kerakli funksiyani. Angular standalone component'lar modul butunligini import qilmasdan faqat kerakli directive/pipe oladi. Side-effect import'lardan (import 'something') saqlaning.

Kod misoli

// ❌ Butun lodash bundle'ga tushadi
import _ from 'lodash';
const sorted = _.sortBy(users, 'name');

// ✅ Tree-shakeable
import { sortBy } from 'lodash-es';
const sorted = sortBy(users, 'name');

// ❌ Butun RxJS operators
import * as operators from 'rxjs/operators';

// ✅ Faqat keraklisi
import { map, filter, debounceTime } from 'rxjs/operators';
// Angular — faqat kerakli import
@Component({
  standalone: true,
  imports: [
    NgIf,        // faqat NgIf — butun CommonModule emas
    AsyncPipe,
    RouterLink,
  ],
})
export class LeanComponent {}
// angular.json — production optimizatsiya
{
  "optimization": true,
  "sourceMap": false,
  "namedChunks": false,
  "buildOptimizer": true
}

Imtihonda

  • Tree shaking qachon ishlamaydi (side effects)?
  • providedIn: 'root' service tree shake bo'ladimi?
  • Bundle analyzer bilan qanday tekshiriladi (ng build --stats-json)?

Yodlash uchun

Named import; standalone + selective imports; lodash-es.

`ng build --stats-json` + webpack-bundle-analyzer yoki `source-map-explorer` bilan qaysi paket katta ekanini ko'ring.
Prev
Komponent arxitekturasi
Next
SOLID va Clean Code