Pretius: strategiczna fuzja jako odpowiedź na współczesne wyzwania
Pretius. Budujemy mądrzej:
strategiczna fuzja jako odpowiedź na współczesne wyzwania

Funkcje Angular 19: dogłębna analiza

Hanna Domagała

Frontend Developer

  • 9 stycznia, 2025

Spis

[Uwaga] Ten artykuł został pierwotnie przygotowany w języku angielskim i został przetłumaczony na język polski.

1. Incremental Hydration w wersji developer preview

Hydration (hydracja) to proces „aktywacji” strony renderowanej po stronie serwera na kliencie poprzez dodanie interaktywności. Gdy aplikacja jest renderowana po stronie serwera (SSR), serwer generuje dokument HTML i wysyła go do klienta. Po stronie klienta Angular musi przejąć kontrolę i dodać interaktywność do statycznego kodu HTML – proces ten nazywamy właśnie „hydracją”.

W tradycyjnym Angular SSR (przeczytaj więcej o implementacji Angular SSR w artykule mojego kolegi – Pawła Żurawskiego), cała aplikacja podlega procesowi hydracji za jednym razem, gdy tylko klient otrzyma HTML. Może to być nieefektywne, zwłaszcza jeśli aplikacja jest duża lub złożona, ponieważ cała strona musi zostać poddana procesowi bootstrapu jednocześnie, co może prowadzić do opóźnień w uzyskaniu interaktywności strony.

Incremental hydration to przełomowa funkcja mająca na celu optymalizację wydajności aplikacji renderowanych po stronie serwera poprzez usprawnienie ładowania i wykonywania kodu JavaScript po stronie klienta. Funkcja ta pomaga skrócić czas potrzebny na uzyskanie interaktywności strony poprzez stopniowy bootstrapping części aplikacji, zamiast robienia tego wszystkiego naraz. Angular inkrementalnie hydruje mniejsze części aplikacji w miarę potrzeb. Dzięki hydracji tylko niezbędnych fragmentów, incremental hydration może również pomóc zminimalizować wpływ nieużywanego JavaScriptu, co dodatkowo poprawia wydajność.

Jak to działa?

Dzięki incremental hydration Angular dzieli aplikację na mniejsze „strefy hydracji” (hydration zones) lub „chunki hydracji” (hydration chunks). Gdy klient otrzyma wyrenderowany na serwerze HTML, Angular najpierw rozpocznie hydrację istotnych lub widocznych części strony. Gdy staną się one interaktywne, Angular będzie kontynuował hydrację pozostałych obszarów strony w tle.

Incremental hydration pozwala oznaczać sekcje szablonu za pomocą znanej składni @defer (wprowadzonej w Angularze 17), instruując Angulara, aby ładował je leniwie (lazy load) i hydrował tylko wtedy, gdy wystąpią określone triggery.

Przykład:

@defer (hydrate on viewport) {
 <your-component />
}

Więcej o incremental hydration możesz przeczytać w dokumentacji.

2. Event replay staje się stabilny

Event replay to funkcja w Angularze, która zapewnia płynne wykonywanie interakcji użytkownika w aplikacjach renderowanych po stronie serwera (SSR) lub częściowo hydrowanych.

Mechanizm ten przechwytuje i kolejkuję interakcje użytkownika (np. kliknięcia, wysłania formularzy, przewijanie), które wystąpią, zanim aplikacja zostanie w pełni hydrowana. Gdy proces hydracji zostanie zakończony, a JavaScript po stronie klienta przejmie kontrolę, te zakolejkowane zdarzenia są odtwarzane (replayed) i obsługiwane tak, jakby wystąpiły już po hydracji.

Począwszy od wersji Angular 19, event replay jest stabilny i domyślnie włączony dla wszystkich nowych aplikacji korzystających z server-side renderingu, co czyni je bardziej solidnymi i interaktywnymi bez konieczności dodatkowej konfiguracji.

Angular CLI będzie teraz domyślnie generować taką konfigurację:

bootstrapApplication(App, {
  providers: [
    provideClientHydration(withEventReplay())
  ]
});

3. Standalone jako domyślny tryb

Komponenty standalone zostały wprowadzone w v14, a ponad 90% programistów w ostatniej ankiecie zadeklarowało, że korzysta z tej funkcji. W Angularze 19 komponenty standalone są teraz domyślnym sposobem definiowania i budowania komponentów. Zmiana ta upraszcza metadane wszystkich komponentów standalone, dyrektyw i pipe’ów.

Podczas aktualizacji do v19, CLI automatycznie usunie właściwość metadanych standalone dla wszystkich abstrakcji typu standalone, a dla tych, które nie są standalone, ustawi ją na false.

4. Rygorystyczne wymuszanie standalone

Aby wymusić stosowanie nowoczesnych API w projekcie, wprowadzono nową flagę kompilatora. Wygeneruje ona błąd, jeśli wykryje komponent, dyrektywę lub pipe, który nie jest typu standalone. Aby włączyć tę funkcję, skonfiguruj plik tsconfig.json w następujący sposób:

{
  "angularCompilerOptions": {
    "strictStandalone": true
  }
}

[..]
[ERROR] TS-992023: Only standalone components/directives are allowed when 'strictStandalone' is enabled. [plugin angular-compiler]

5. Eksperymentalny reaktywny prymityw: linkedSignal

Funkcja linkedSignal w Angularze to eksperymentalne API, które wprowadza nowy sposób zarządzania stanem ściśle powiązanym z innymi stanami reaktywnymi. Funkcja ta jest szczególnie przydatna w scenariuszach, w których dany fragment stanu zależy od innego i powinien być odpowiednio aktualizowany, gdy stan źródłowy ulegnie zmianie.

linkedSignal tworzy writable signal (sygnał z możliwością zapisu), który automatycznie aktualizuje swoją wartość na podstawie funkcji obliczeniowej (computation function) za każdym razem, gdy jego sygnał źródłowy ulegnie zmianie. Zapewnia to spójność stanu zależnego z jego źródłem.

W przeciwieństwie do sygnałów typu computed, które są tylko do odczytu, linkedSignal pozwala na ręczne aktualizacje. Oznacza to, że można ustawić jego wartość bezpośrednio, co zapewnia elastyczność w zarządzaniu stanami, które mogą wymagać zarówno automatycznych, jak i ręcznych korekt.

Jak to działa?

W prostszych scenariuszach można użyć skróconej składni:

animals = signal(['guinea pig', 'cat', 'dog']);

selectedAnimal = linkedSignal(() => animals()[0]);
console.log(selectedAnimal()); // 'guinea pig'

animals.set(['elephant','rabbit']);
console.log(selectedAnimal()); // 'elephant'

Za każdym razem, gdy tablica animals się zmienia, selectedAnimal zmieni się na pierwszy element z nowej listy.

W niektórych przypadkach nowa wartość musi zostać obliczona na podstawie poprzedniej wartości. Wówczas warto rozważyć bardziej zaawansowaną składnię z definicją źródła (source) i obliczeń (computation):

animals = signal<string[]>(['guinea pig', 'cat', 'dog']);

selectedAnimal = linkedSignal({
    source: animals,
    computation: (newAnimals: string[], previous?: { value: string }) => {
      // Jeśli poprzedni wybór istnieje na nowej liście, zachowaj go. W przeciwnym razie wybierz pierwsze zwierzę.
      return previous && newAnimals.includes(previous.value)
        ? previous.value
        : newAnimals[0];
    },
  });

// Zachowaj obecny wybór podczas resetowania listy zwierząt (np. po ponownym pobraniu z API)
console.log(this.selectedAnimal()); // 'guinea pig'
this.animals.set(['horse', 'guinea pig']);
console.log(this.selectedAnimal()); // 'guinea pig'
this.animals.set(['horse', 'fish']);
console.log(this.selectedAnimal()); // 'horse'

// Ponieważ linkedSignal jest zapisywalny, zwierzę może zostać wybrane również ręcznie (np. po kliknięciu w UI)
this.selectedAnimal.set('dog');
console.log(this.selectedAnimal()); // 'dog'

Więcej o linkedSignals przeczytasz w dokumentacji.

6. Eksperymentalne usprawnienie pobierania danych: API resource i rxResource

Angular 19 wprowadza eksperymentalne API resource oraz rxResource, aby usprawnić asynchroniczne pobieranie i zarządzanie danymi poprzez wykorzystanie sygnałów oraz obserwowalnych (observables). Warto zaznaczyć, że oba te interfejsy mogą jeszcze ulec zmianom, zanim staną się stabilne w przyszłych wydaniach.

resource API

Funkcja resource tworzy reaktywne źródło danych, które pobiera asynchroniczne dane i dostarcza sygnały do monitorowania ich stanu.

Główne cechy:

  • Reaktywne żądania (Reactive requests) – Definiujesz funkcję żądania, która zwraca parametry na podstawie sygnałów. Gdy sygnały te ulegną zmianie, funkcja loader wykonuje się ponownie, aby pobrać zaktualizowane dane.
  • Funkcja Loader – Wykonuje operację asynchroniczną, zwracając Promise z wartością zasobu. Otrzymuje ona abortSignal, aby umożliwić anulowanie żądania, gdy parametry zmienią się w trakcie trwającego pobierania.
  • Zarządzanie stanem – Dostęp do stanu zasobu odbywa się poprzez sygnały takie jak value, status, error, oraz isLoading, co pozwala na efektywną obsługę stanów ładowania i błędów.

Przykład użycia:

const RESOURCE_URL = 'https://lorem.ipsum';
const id = signal(1);

const myResource = resource({
  request: () => ({ id: id() }),
  loader: ({ request, abortSignal }) =>
    fetch(${RESOURCE_URL}${request.id}, { signal: abortSignal }).then(response => response.json()),
});

W tym przykładzie myResource pobiera dane na podstawie id signal. Zmiana id powoduje nowe pobranie, przy czym poprzednie żądanie jest przerywane, jeśli wciąż było w toku.

rxResource API

Funkcja rxResource oferuje podobną funkcjonalność, jednak podczas gdy resource() korzysta z loadera opartego na promise, rxResource() integruje się z RxJS observables. Jest to rozwiązanie dedykowane programistom preferującym strumienie do operacji asynchronicznych. Nadaje się do bardziej złożonych scenariuszy i wykorzystuje pełną moc RxJS do obsługi ponowień (retries), anulowań, łączenia strumieni i innych. Obecnie rxResource bierze pod uwagę tylko pierwszą wyemitowaną wartość z observable; kolejne emisje są ignorowane.

Przykład użycia:

const RESOURCE_URL = 'https://lorem.ipsum';
const id = signal(1);

const myRxResource = rxResource({
  request: () => ({ id: id() }),
  loader: ({ request }) =>
    fromFetch(${RESOURCE_URL}${request.id}).pipe(
      switchMap(response => response.json())
    ),
});

Tutaj myRxResource pobiera dane jako strumień observable, reagując na zmiany w sygnale id.

7. Hybrid rendering (konfiguracja server route) w wersji developer preview

W Angularze 19 wprowadzono konfigurację tras serwera (server route configuration), aby zapewnić programistom precyzyjną kontrolę nad sposobem renderowania każdej ścieżki w aplikacji. Funkcja ta pozwala określić tryb renderowania dla poszczególnych route’ów, dając wybór między Server-Side Rendering (SSR), Static Site Generation (SSG), a Client-Side Rendering (CSR).

Jak to działa?

Aby skonfigurować trasy serwera, definiujesz tablicę obiektów ServerRoute, zazwyczaj w pliku o nazwie app.routes.server.ts. Każdy ServerRoute określa ścieżkę oraz odpowiadający jej tryb renderowania przy użyciu enuma RenderMode.

Przykład użycia:

import { RenderMode, ServerRoute } from '@angular/ssr';
export const serverRoutes: ServerRoute[] = [
  {
    path: '', // Ścieżka główna
    renderMode: RenderMode.Client, // Renderowane po stronie klienta (CSR)
  },
  {
    path: 'about',
    renderMode: RenderMode.Prerender, // Prerenderowane w czasie budowania (SSG)
  },
  {
    path: 'profile',
    renderMode: RenderMode.Server, // Renderowane na serwerze przy każdym żądaniu (SSR)
  },
  {
    path: '**', // Ścieżka typu wildcard dla pozostałych tras
    renderMode: RenderMode.Server, // Domyślnie SSR
  },
];

Angular 19 wprowadza trzy tryby renderowania, które można przypisać do tras:

  • Server (RenderMode.Server) – Renderuje aplikację na serwerze dla każdego żądania, dostarczając w pełni wypełnioną stronę HTML. Jest to korzystne dla dynamicznych treści, które zmieniają się w zależności od użytkownika lub żądania.
  • Prerender (RenderMode.Prerender) – Generuje statyczne pliki HTML w czasie budowania dla określonych tras. Idealne dla treści statycznych, które nie zmieniają się często, zwiększając wydajność dzięki generowaniu statycznemu (SSG).
  • Client (RenderMode.Client) – Renderuje aplikację w całości w przeglądarce, zgodnie z tradycyjnym podejściem client-side rendering.

8. Ostrzeżenia o nieużywanych importach standalone

Począwszy od Angulara 19, Angular CLI zawiera funkcję zgłaszania ostrzeżeń dotyczących nieużywanych importów w aplikacji. To ulepszenie ma na celu poprawę czystości kodu i produktywności programistów poprzez pomoc w identyfikacji niepotrzebnych lub przestarzałych importów w plikach projektu.

Przykład:

@Component({
  selector: 'test-component',
  imports: [IconComponent],
  templateUrl: './test-component.component.html',
})

[...]

[WARNING] TS-998113: All imports are unused [plugin angular-compiler]
imports: [IconComponent]

Podsumowanie

Angular ewoluuje dynamicznie – 19. wersja przynosi mnóstwo ulepszeń, które podnoszą komfort pracy dewelopera (developer experience) oraz ogólną wydajność aplikacji. Przeanalizuj te funkcjonalności i zacznij wdrażać je we własnych projektach Angularowych – z pewnością ułatwią Ci one życie w wielu sytuacjach.

Jeśli interesuje Cię więcej treści o Angularze, sprawdź inne publikacje na naszym blogu:

  1. Angular SSR: Your server-side rendering implementation guide
  2. Angular vs React: In-depth comparison of the most popular front-end technologies
  3. Angular MVVM, MVC, CBA – A look at different approaches to application architecture
  4. Keycloak-Angular integration: Practical tutorial for connecting your app to a powerful IAM system
  5. AngularJS upgrade: Why 2023 is the time for migrating and how to do it

Angular 19 FAQ

Oto odpowiedzi na kilka powszechnych pytań dotyczących aplikacji Angular, jego funkcji oraz rozwoju.

Jaka jest aktualna wersja Angulara?

Aktualna wersja to Angular 19.

Jakie są najlepsze nowe funkcje Angulara 19?

Wśród najważniejszych funkcji znajdują się: incremental hydration, stabilny event replay, zmiany w komponentach standalone, nowy eksperymentalny prymityw linked signal, eksperymentalne API do strumieniowego pobierania danych, hybrydowe renderowanie oraz ostrzeżenia o nieużywanych importach standalone.

Kiedy odbyła się premiera Angulara 19?

Angular 19 został wydany 19 listopada 2024 roku.

Czym jest Angular Material UI?

To kompleksowa biblioteka komponentów zgodna z Material Design, przeznaczona dla Angulara.

Czym jest Angular language service?

Angular Language Service to usługa wspomagająca edytory kodu w obsłudze błędów, ich identyfikacji, podpowiadaniu składni (completions), wyświetlaniu wskazówek oraz nawigacji wewnątrz szablonów Angulara.

Czym jest hot module replacement w Angularze?

Hot module replacement (HMR) pozwala deweloperom na wymianę komponentów i modułów aplikacji w czasie rzeczywistym (w trakcie działania programu) bez utraty stanu aplikacji.

Szukasz firmy tworzącej oprogramowanie?

Pracuj z zespołem, który pomógł już dziesiątkom rynkowych liderów. Umów spotkanie, by dowiedzieć się:

  • Jak działają nasze produkty
  • Jak możesz oszczędzić czas i pieniądze
  • Czym nasze rozwiązania różnią się od konkurencji

Przebieg kontaktu z Pretius

Dbamy o bezpieczeństwo Twoich danych: Certyfikat ISO

Działamy zgodnie z normą ISO 27001, zapewniając najwyższy poziom bezpieczeństwa Twoich danych.
certified dekra 27001
© 2026 Pretius. All right reserved.