Питання співбесіди Angular 19: Signals, SSR і обов'язкові концепції

Найпоширеніші питання співбесіди з Angular 19: Signals, інкрементальна гідратація, zoneless change detection і нові реактивні API з прикладами коду та очікуваними відповідями.

Питання співбесіди Angular 19: Signals, SSR та інкрементальна гідратація

Співбесіди з Angular у 2026 році виходять далеко за межі компонентів і сервісів. Angular 19, випущений у листопаді 2024 року, приніс фундаментальні архітектурні зміни: стабільні Signals, SSR з інкрементальною гідратацією та zoneless change detection. Опанування цих концепцій відрізняє мід-кандидатів від сеньйорів.

Що оцінюють інтерв'юери у 2026

Питання з Angular 19 фокусуються на трьох сферах: дрібнозерниста реактивність із Signals, продуктивність SSR через інкрементальну гідратацію та здатність проєктувати застосунки без Zone.js. Очікувані відповіді демонструють архітектурне розуміння, а не лише знання синтаксису.

Angular 19 Signals: нова модель реактивності

Signals представляють найґрунтовнішу зміну в Angular з моменту запровадження change detection. Signal — це синхронне реактивне значення, яке автоматично сповіщає своїх споживачів про зміни.

Типове питання: "У чому різниця між Signal і RxJS Observable?"

Очікувана відповідь чітко розрізняє обидві моделі:

signals-vs-observables.tstypescript
import { signal, computed, effect } from '@angular/core';

// Signal: synchronous, value always available
const count = signal(0);
const doubled = computed(() => count() * 2); // Recomputed only when count changes

// Effect: reacts to signal changes
effect(() => {
  console.log(`Count: ${count()}, Doubled: ${doubled()}`);
});

count.set(5); // Immediate, synchronous notification

Signals використовують дрібнозернистий граф залежностей. На відміну від RxJS, який обробляє складні асинхронні робочі процеси (retry, debounce, merge), Signals оптимізують синхронну реактивність UI. Angular 19 рекомендує Signals для стану компонентів і RxJS для асинхронних потоків (HTTP-запити, WebSockets).

Signal Inputs та Queries: міграція з @Input()

Angular 19 стабілізує signal-based API для inputs, outputs і queries. Це питання регулярно з'являється на співбесідах.

Типове питання: "Як мігрувати класичний @Input() до Signal Input?"

user-card.component.tstypescript
import { Component, input, computed } from '@angular/core';

@Component({
  selector: 'app-user-card',
  template: `
    <div class="card">
      <h3>{{ fullName() }}</h3>
      <span>{{ role() }}</span>
    </div>
  `
})
export class UserCardComponent {
  // Signal inputs: strict typing, optional default value
  firstName = input.required<string>();
  lastName = input.required<string>();
  role = input<string>('developer'); // Default value

  // Computed derived from inputs: automatically recomputed
  fullName = computed(() => `${this.firstName()} ${this.lastName()}`);
}

Ключова перевага: Signal Inputs дозволяють створювати значення computed() напряму, без lifecycle hooks. Більше не потрібен ngOnChanges для реакції на зміни input. Angular надає schematic signal-input-migration для автоматизації міграції.

linkedSignal: синхронізація залежного стану

linkedSignal — експериментальне API Angular 19, що створює записуваний signal, прив'язаний до джерела. Ця концепція часто з'являється на сеньйорних співбесідах.

Типове питання: "Як обробляти змінюваний похідний стан за допомогою linkedSignal?"

product-filter.component.tstypescript
import { signal, linkedSignal } from '@angular/core';

// Category list that can change
const categories = signal(['frontend', 'backend', 'devops']);

// Linked selection: resets when categories change
const selectedCategory = linkedSignal({
  source: categories,
  computation: (cats) => cats[0] // Reset to first element
});

// Manual modification still possible
selectedCategory.set('backend');

// When categories changes, selectedCategory resets automatically
categories.set(['mobile', 'data', 'cloud']);
// selectedCategory() === 'mobile'

Конкретний випадок використання: dropdown фільтра, вибір якого скидається при зміні джерельного списку. Без linkedSignal цей патерн вимагав effect() із set() — антипатерн, що створює цикли оновлення.

Пастка на співбесіді: effect() з set()

Виклик signal.set() всередині effect() — це антипатерн, який Angular виявляє. Фреймворк видає попередження в режимі розробки. Правильне рішення: використовувати linkedSignal або computed() залежно від того, чи має похідне значення бути записуваним.

Resource API: завантаження асинхронних даних із Signals

Angular 19 представляє експериментальне API resource для асинхронного завантаження даних. Це API замінює класичний патерн service + subscribe у компонентах.

user-profile.component.tstypescript
import { resource, signal } from '@angular/core';
import { inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';

const userId = signal(42);
const http = inject(HttpClient);

// Resource: links a source signal to an async loader
const userResource = resource({
  request: () => ({ id: userId() }),  // Recomputed when userId changes
  loader: async ({ request }) => {
    const response = await fetch(`/api/users/${request.id}`);
    return response.json();
  }
});

// Access in template
// userResource.value()   -> data (or undefined)
// userResource.isLoading() -> boolean
// userResource.error()    -> error if any

Демонстрація знання resource versus rxResource (RxJS-версія) на співбесіді свідчить про активне технологічне відстеження. rxResource використовує Observables як loader, що корисно для команд із наявною кодовою базою RxJS.

Готовий до співбесід з Angular?

Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.

SSR та інкрементальна гідратація в Angular 19

Angular 19 виводить SSR на новий рівень з інкрементальною гідратацією у developer preview. Ця функція, протестована у масштабах Google Search, стає дедалі частішою темою співбесід.

Типове питання: "Як працює інкрементальна гідратація в Angular 19?"

Класична гідратація відтворює все дерево компонентів на стороні клієнта після серверного рендерингу. Інкрементальна гідратація гідратує лише необхідні компоненти, у момент, коли вони стають видимими або інтерактивними.

product-page.component.tstypescript
import { Component } from '@angular/core';

@Component({
  template: `
    <app-header />
    <app-product-details [id]="productId" />

    <!-- Hydrated only when visible in viewport -->
    @defer (on viewport) {
      <app-reviews [productId]="productId" />
    }

    <!-- Hydrated only on user interaction -->
    @defer (on interaction) {
      <app-comment-form />
    }
  `
})
export class ProductPageComponent {
  productId = 'angular-19-guide';
}

Директива @defer точно контролює момент гідратації. Доступні тригери: on viewport (видимий), on interaction (клік, focus), on idle (браузер у простої), on timer(5s) (затримка). Контент залишається видимим як статичний HTML до гідратації, без блимання.

Render mode на рівні маршруту: гранульований SSR за маршрутом

Angular 19 представляє render mode на рівні маршруту, що дозволяє співіснувати SSR, SSG і CSR в межах одного застосунку.

app.routes.server.tstypescript
import { RenderMode, ServerRoute } from '@angular/ssr';

export const serverRoutes: ServerRoute[] = [
  // Marketing pages: pre-rendered at build time (SSG)
  { path: '', renderMode: RenderMode.Prerender },
  { path: 'pricing', renderMode: RenderMode.Prerender },

  // Dashboard: server-rendered on each request (SSR)
  { path: 'dashboard/**', renderMode: RenderMode.Server },

  // Interactive editor: client-side only (CSR)
  { path: 'editor/**', renderMode: RenderMode.Client },
];

На співбесідах здатність обґрунтувати вибір render mode для маршруту демонструє розуміння компромісів між продуктивністю, SEO та інтерактивністю. Статичні сторінки (landing, blog) виграють від prerender. Динамічні сторінки з даними користувача використовують SSR. Високоінтерактивні застосунки залишаються на CSR.

Zoneless change detection: архітектура без Zone.js

Zoneless change detection — найзначніша архітектурна еволюція Angular 19. Це питання стало обов'язковим на сеньйорних співбесідах.

Типове питання: "Як працює change detection без Zone.js?"

main.tstypescript
import { bootstrapApplication } from '@angular/platform-browser';
import {
  provideExperimentalZonelessChangeDetection
} from '@angular/core';
import { AppComponent } from './app.component';

bootstrapApplication(AppComponent, {
  providers: [
    provideExperimentalZonelessChangeDetection()
  ]
});

Без Zone.js Angular більше не патчить асинхронні API браузера (setTimeout, Promise, addEventListener). Change detection запускається виключно через Signals. Вимірні переваги:

  • Зменшення розміру bundle на 10-15 KB (zone.js видалено)
  • Чисті stack trace без фреймів Zone.js
  • Цільова change detection: лише компоненти, на які впливає змінений Signal, перевідрендерюються
Angular 20.2: zoneless стає стабільним

З Angular 20.2 zoneless-режим стабільний з provideZonelessChangeDetection() (без префікса Experimental). Згадка цього прогресу на співбесіді демонструє активне відстеження екосистеми.

Standalone за замовчуванням: кінець NgModules

Angular 19 робить standalone-компоненти поведінкою за замовчуванням. Прапор standalone: true більше не потрібен. Це рішення спрощує архітектуру і зменшує шаблонний код.

Типове питання: "Який вплив standalone-by-default на архітектуру Angular-застосунку?"

dashboard.component.tstypescript
@Component({
  selector: 'app-dashboard',
  imports: [CommonModule, RouterModule, UserCardComponent],
  template: `
    <nav>
      <a routerLink="/home">Home</a>
    </nav>
    @for (user of users(); track user.id) {
      <app-user-card [firstName]="user.firstName" [lastName]="user.lastName" />
    }
  `
})
export class DashboardComponent {
  users = signal<User[]>([]);
}

Кожен компонент явно декларує свої залежності через imports. NgModules залишаються доступними для зворотної сумісності, але нові застосунки Angular 19+ більше їх не потребують. На співбесідах цінується вміння пояснити інкрементальну міграцію (компонент за компонентом) замість підходу big bang.

Стратегії відповідей на співбесідах з Angular 19

Технічні інтерв'юери оцінюють три виміри щодо Angular 19:

  • Архітектурне розуміння: пояснення, чому Signals поступово замінюють Zone.js, а не лише як їх використовувати
  • Компроміси: знання, коли використовувати computed() versus linkedSignal versus effect() і коли зберегти RxJS
  • Міграція: опис інкрементальної стратегії міграції з класичного Angular-застосунку до Signals і zoneless-режиму

Ключ: уникати декламування офіційної документації Angular. Кожна відповідь має бути проілюстрована конкретним випадком використання з реального проєкту, складною формою, e-commerce-сторінкою з SSR, дашбордом у реальному часі.

Для фундаментальних концепцій Angular перед співбесідою див. повний посібник з 25 питань співбесіди Angular.

Висновок

  • Angular 19 Signals замінюють патерни @Input() + ngOnChanges дрібнозернистою синхронною реактивною моделлю. signal(), computed() та input() покривають 90% випадків використання
  • linkedSignal вирішує змінюваний похідний стан без звернення до антипатерну effect() + set()
  • Інкрементальна гідратація через @defer зменшує Time to Interactive без жертвування SEO. Кожен компонент гідратується відповідно до свого тригера
  • Zoneless-режим прибирає Zone.js з bundle і націлює change detection лише на компоненти, на які впливає Signal
  • Render mode на рівні маршруту дозволяє змішувати SSG, SSR і CSR в одному застосунку залежно від потреб кожної сторінки
  • Компоненти standalone-by-default усувають потребу в NgModules у нових застосунках
  • На співбесідах демонстрація компромісів (Signals vs RxJS, SSR vs CSR, zoneless vs Zone.js) важливіша за синтаксис

Починай практикувати!

Перевір свої знання з нашими симуляторами співбесід та технічними тестами.

Теги

#angular
#interview
#signals
#ssr
#angular-19

Поділитися

Пов'язані статті