AngularAtlasAusg. 22.2

Kap. 16Fortgeschrittene UI & Performance69 / 75

Riesige Listen: Virtual Scroll

100.000 Zeilen ohne Ruckeln: CDK Virtual Scroll, itemSize, trackBy und die Alternativen (Paginierung, Infinite Scroll).

~0 Min. Lesezeit Offizielle Doku

Jede Zeile in einer Liste bedeutet DOM-Elemente, berechnete Styles, Layout und in Angular einen View mit Bindings, die von der Change Detection geprüft werden. Bei ein paar hundert Zeilen merkst du nichts davon. Bei Zehntausenden braucht die Seite Sekunden zum Starten, das Scrollen ruckelt und der Speicherverbrauch wächst stetig. Die klassische Lösung: nicht rendern, was man nicht sieht.

Virtual Scroll hält nur die Zeilen im sichtbaren Bereich im DOM, plus einen Puffer darüber und darunter. Beim Scrollen werden dieselben Elemente für andere Daten wiederverwendet. Die Gesamtgröße der Liste wird simuliert, sodass die Scrollleiste aussieht, als gehörte sie zur ganzen Liste.

Warum das wichtig ist
OnPush-Komponenten und Signals verringern, wie oft du renderst. Sie verringern nicht, wie viel du renderst. Bei 100.000 Zeilen liegt das Problem in der Anzahl der Knoten, nicht in der Change Detection. Nur Virtualisierung, Paginierung oder das Laden in Blöcken löst es.

CDK Virtual Scroll

Aus @angular/cdk/scrolling nutzt du drei Standalone-Bausteine: CdkVirtualScrollViewport (der Container mit Scroll), CdkFixedSizeVirtualScroll (die Strategie: das Attribut itemSize) und CdkVirtualForOf (die Direktive *cdkVirtualFor, die @for ersetzt). Der Viewport braucht eine Höhe, und itemSize muss exakt der tatsächlichen Höhe einer Zeile in Pixeln entsprechen. Die Strategie berechnet daraus, welche Indizes sichtbar sind.

import { CdkFixedSizeVirtualScroll, CdkVirtualForOf, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';

@Component({
  selector: 'app-orders',
  imports: [CdkVirtualScrollViewport, CdkFixedSizeVirtualScroll, CdkVirtualForOf],
  template: `
    <cdk-virtual-scroll-viewport itemSize="36" class="viewport">
      <div class="row" *cdkVirtualFor="let o of orders(); trackBy: byId">
        {{ o.id }} · {{ o.customer }} · {{ o.total }}
      </div>
    </cdk-virtual-scroll-viewport>
  `,
  styles: `
    .viewport { height: 480px; }       /* der Viewport MUSS eine Höhe haben */
    .row { height: 36px; }             /* = itemSize, exakt */
  `,
})
export class Orders {
  readonly orders = input.required<Order[]>();
  protected readonly byId = (_: number, o: Order) => o.id;
}
@for virtualisiert nicht
Der @for-Block rendert immer alle Elemente. Für Virtualisierung brauchst du die Direktive *cdkVirtualFor, die vom Viewport den Bereich der zu rendernden Indizes erhält.
Live100.000 Zeilen (echtes CDK)
DOM-Elemente in der Liste: 0erstes Rendering: 0 mserste sichtbare Zeile: #1
Sieh dir den Zähler „DOM-Elemente“ an: Im virtuellen Modus bleiben ein paar hundert übrig, egal wie weit du scrollst. Spring mit scrollToIndex zu Zeile 50.000. Wechsle zu einem normalen @for: nur 5.000 Zeilen, aber zig-mal mehr Knoten und ein sichtbar langsameres erstes Rendering.

Der Puffer und das Recycling von Views

minBufferPx und maxBufferPx steuern den Puffer, der außerhalb des Bildschirms gerendert wird. Fällt der Puffer unter minBufferPx, rendert der Viewport neue Zeilen, bis er maxBufferPx erreicht. Ein größerer Puffer bedeutet weniger Lücken beim schnellen Scrollen, aber mehr DOM. Views, die den Bildschirm verlassen, werden in einem Cache (templateCacheSize) gehalten und wiederverwendet. Deshalb ist trackBy wichtig: Ohne es wird bei jedem Scrollen viel mehr DOM neu erzeugt als nötig.

<!-- minBufferPx: Fällt der Puffer (oben und unten) unter so viele px, wird mehr gerendert … maxBufferPx: … bis so viele px erreicht sind -->
<cdk-virtual-scroll-viewport
  itemSize="36"
  minBufferPx="360"
  maxBufferPx="720"
  (scrolledIndexChange)="first.set($event)">
  <div *cdkVirtualFor="let r of rows; trackBy: byId; templateCacheSize: 40">…</div>
</cdk-virtual-scroll-viewport>

Variable Höhen und weitere Grenzen

Die Standardstrategie geht von Zeilen gleicher Höhe aus. Eine Autosize-Strategie für Elemente unterschiedlicher Größe gibt es in @angular/cdk-experimental, doch die CDK-Dokumentation sagt ausdrücklich, dass sie nicht produktionsreif ist. Wenn sich deine Zeilen unterscheiden, hast du drei Möglichkeiten:

  • sie auf dieselbe Höhe bringen (abgeschnittener Text, Details per Klick);
  • eine eigene VirtualScrollStrategy schreiben;
  • eine der Alternativen unten wählen.

Dazu kommt ein UX-Preis: Zeilen, die nicht gerendert sind, existieren nicht im DOM. Strg+F findet sie nicht, und Screenreader wissen nichts von ihnen.

Alternativen: Laden in Blöcken

Viele Listen brauchen keine Virtualisierung, sie dürfen nur nicht alles auf einmal laden. Paginierung ist die einfachste und zugänglichste Lösung. Infinite Scroll fügt Seiten hinzu, wenn der Benutzer ein „Sentinel“-Element erreicht, das mit IntersectionObserver oder mit @defer (on viewport) beobachtet wird (siehe @defer). Die CSS-Eigenschaft content-visibility: auto lässt das DOM vollständig, überspringt aber Layout und Zeichnen für alles außerhalb des Bildschirms.

// Infinite scroll: ein „Sentinel“-Element am Ende + IntersectionObserver
afterNextRender(() => {
  const io = new IntersectionObserver(
    ([entry]) => entry.isIntersecting && this.loadNextPage(),
    { rootMargin: '0px 0px 200px 0px' },   // beginne 200 px früher mit dem Laden
  );
  io.observe(this.sentinel().nativeElement);
  this.destroyRef.onDestroy(() => io.disconnect());
});
LiveInfinite Scroll mit Sentinel
geladen: 50 / 1.000DOM-Elemente: 0
#1Ana PopescuCluj-Napoca0,0
#2Mihai PetrescuTimișoara791,9
#3Ioana ConstantinSibiu1.583,8
#4Radu GeorgescuBucurești2.375,7
#5Elena MarinBrașov3.167,6
#6Andrei StanOradea3.959,5
#7Maria DumitruIași4.751,4
#8Vlad IonescuConstanța5.543,3
#9Cristina PopescuCluj-Napoca6.335,2
#10Bogdan PetrescuTimișoara7.127,1
#11Ana ConstantinSibiu7.919,0
#12Mihai GeorgescuBucurești8.710,9
#13Ioana MarinBrașov9.502,8
#14Radu StanOradea294,7
#15Elena DumitruIași1.086,6
#16Andrei IonescuConstanța1.878,5
#17Maria PopescuCluj-Napoca2.670,4
#18Vlad PetrescuTimișoara3.462,3
#19Cristina ConstantinSibiu4.254,2
#20Bogdan GeorgescuBucurești5.046,1
#21Ana MarinBrașov5.838,0
#22Mihai StanOradea6.629,9
#23Ioana DumitruIași7.421,8
#24Radu IonescuConstanța8.213,7
#25Elena PopescuCluj-Napoca9.005,6
#26Andrei PetrescuTimișoara9.797,5
#27Maria ConstantinSibiu589,4
#28Vlad GeorgescuBucurești1.381,3
#29Cristina MarinBrașov2.173,2
#30Bogdan StanOradea2.965,1
#31Ana DumitruIași3.757,0
#32Mihai IonescuConstanța4.548,9
#33Ioana PopescuCluj-Napoca5.340,8
#34Radu PetrescuTimișoara6.132,7
#35Elena ConstantinSibiu6.924,6
#36Andrei GeorgescuBucurești7.716,5
#37Maria MarinBrașov8.508,4
#38Vlad StanOradea9.300,3
#39Cristina DumitruIași92,2
#40Bogdan IonescuConstanța884,1
#41Ana PopescuCluj-Napoca1.676,0
#42Mihai PetrescuTimișoara2.467,9
#43Ioana ConstantinSibiu3.259,8
#44Radu GeorgescuBucurești4.051,7
#45Elena MarinBrașov4.843,6
#46Andrei StanOradea5.635,5
#47Maria DumitruIași6.427,4
#48Vlad IonescuConstanța7.219,3
#49Cristina PopescuCluj-Napoca8.011,2
#50Bogdan PetrescuTimișoara8.803,1
mehr wird geladen, sobald du hier ankommst…
Scrolle durch die Liste: Sobald sich das Sentinel am Ende dem sichtbaren Bereich nähert, werden weitere 50 Zeilen geladen. Die Anzahl der DOM-Elemente wächst mit jeder Seite. Das ist der Unterschied zu Virtual Scroll.

Wann ja, wann nein

Virtualisieren
  • Tausende oder Millionen Zeilen, bereits im Speicher: Logs, Transaktionen, Datentabellen.
  • Zeilen gleicher Höhe (oder solche, die du auf dieselbe Höhe bringen kannst).
  • Listen, die oft gescrollt werden und bei denen flüssiges Scrollen zählt.
  • Auswahlfelder mit sehr vielen Optionen (ein Dropdown mit 10.000 Einträgen).
Etwas anderes wählen
  • Unter ein paar hundert Zeilen: @for mit track reicht und ist einfacher.
  • Die Daten kommen ohnehin paginiert vom Server: Paginierung oder Infinite Scroll.
  • Inhalte, die Benutzer mit Strg+F durchsuchen oder die vollständig zugänglich sein müssen: Paginierung, content-visibility.
  • Karten mit sehr unterschiedlichen Höhen: content-visibility oder @defer auf Abschnitten.

Häufige Stolperfallen

  • Viewport ohne Höhe: Er dehnt sich auf die Größe der Liste aus und rendert damit alles, also gar keine Virtualisierung. Gib ihm eine feste Höhe oder eine Flex-Höhe.
  • itemSize weicht von der tatsächlichen Höhe ab (Padding, Border, line-height): Zeilen „springen“, es entstehen Lücken, und scrollToIndex landet an der falschen Stelle.
  • Kein trackBy bei Daten, die neu geladen werden: Das gesamte sichtbare DOM wird bei jedem Update neu erzeugt.
  • Der Container ändert seine Größe (ein Panel schließt sich, ein Tab wird aktiviert) und der Viewport weiß nichts davon. Rufe checkViewportSize() auf.
  • Infinite Scroll ohne disconnect() am Observer: Callbacks laufen weiter, nachdem die Komponente zerstört wurde.

Spickzettel

ANZAHL ZEILEN      LÖSUNG
< ~300             einfaches @for mit track
300 – einige Tsd.  Paginierung oder Infinite Scroll (Daten in Blöcken geladen) · content-visibility: auto
Tausende – Mio.    CDK Virtual Scroll (rendert nur, was sichtbar ist + Puffer)

CDK
  Imports          CdkVirtualScrollViewport, CdkFixedSizeVirtualScroll, CdkVirtualForOf (@angular/cdk/scrolling)
  Pflicht          Höhe am Viewport + itemSize = tatsächliche Zeilenhöhe
  Optionen         minBufferPx / maxBufferPx · templateCacheSize · appendOnly · orientation="horizontal"
  API              scrollToIndex(i, 'smooth') · scrolledIndexChange · getRenderedRange() · checkViewportSize()
  variable Höhen   autosize steckt in @angular/cdk-experimental, nicht produktionsreif

STOLPERFALLEN  @for virtualisiert nicht · ohne trackBy wird das DOM bei jedem Scrollen neu erzeugt · Strg+F findet nicht gerenderte Zeilen nicht

Kap. 16 · 0 von 4 abgeschlossen

Lektion abgeschlossen?

Markiere sie, dann erscheint sie auf deiner Karte: im Inhaltsverzeichnis und auf der Startseite.

Wird automatisch markiert, sobald du die ganze Lektion gelesen hast.

  1. Web Workers
  2. Riesige Listen: Virtual Scroll
  3. Moderne Animationen & View Transitions
  4. Memory Leaks finden und beheben
Deine ganze Karte ansehen

Alle 75 Seiten · tippen zum Filtern

  • 01Was ist neu in Angular 21 & 22Alle wichtigen Änderungen in v21 und v22 in Kürze, mit Link zur Seite, die sie jeweils erklärt.Start
  • 01Deine erste App, Schritt für SchrittEine Leseliste, von einer leeren Komponente bis zur fertigen App — Signals, @for, Inputs und Outputs, ein Service und ein Formular, Schritt für Schritt.Start
  • 01Schnelle Entscheidungen„Wohin damit?“, „Signal oder Observable?“, „Shared oder Feature?“ — kurze Antworten auf Alltagsfragen.Start
  • 01Angular-Interviewfragen60 echte Interviewfragen für Junior, Mid und Senior, mit der passenden Antwort, der Nachfrage und den Warnsignalen. Dazu ein Probeinterview.Start
  • 02Standalone & BootstrapWie eine App ohne NgModule startet: bootstrapApplication, app.config.ts, imports in der Komponente.Moderne Grundlagen
  • 02Data Binding & EventsInterpolation, Property- und Attribut-Bindings, Events mit $event und Tastenfiltern und wie [( )] aufgebaut ist — was in das DOM geht und was zurückkommt.Moderne Grundlagen
  • 02Control Flow: @if, @for, @switchDie Block-Syntax, die *ngIf/*ngFor/ngSwitch ersetzt, mit track, @empty und Exhaustive Checks.Moderne Grundlagen
  • 02@let und die neuen Template-AusdrückeLokale Variablen mit @let, Arrow Functions, Spread, Regex, instanceof, Kommentare in Tags.Moderne Grundlagen
  • 02@defer — Lazy Loading in TemplatesSchwere Komponenten nur laden, wenn sie gebraucht werden: Trigger, Prefetch, Placeholder, Loading, Error.Moderne Grundlagen
  • 02Class- & Style-BindingsWarum [class.x] und [style.x] ngClass und ngStyle abgelöst haben (mit automatischer Migration ab v21).Moderne Grundlagen
  • 02Komponenten-Styles & Kapselung:host, die drei Kapselungsmodi, Theming mit CSS-Variablen und warum ::ng-deep der letzte Ausweg ist.Moderne Grundlagen
  • 02Pipes: wann und wiePure vs. Impure Pipes, eigene Pipes und wie du zwischen Pipe, computed() und Methode wählst.Moderne Grundlagen
  • 03signal() und computed()Die reaktiven Grundbausteine: beschreibbarer Zustand, abgeleiteter Zustand, Gleichheit, untracked und Regeln zur Immutability.Signals & Reaktivität
  • 03effect() — wann ja, wann neinMit Signals synchronisierte Seiteneffekte: localStorage, Logging, imperative APIs. Und ihre Stolperfallen.Signals & Reaktivität
  • 03linkedSignal() — editierbarer abgeleiteter ZustandEin Signal, das sich zurücksetzt, wenn sich seine Quelle ändert, das du aber auch manuell setzen kannst.Signals & Reaktivität
  • 03resource, rxResource, httpResourceAsynchrone Daten als Signals: status, value, error, reload, automatischer Abbruch. Stabil seit v22.Signals & Reaktivität
  • 03debounced() — verzögerte SignalsDie „Debounce“-Variante eines Signals, ohne RxJS. Perfekt für die Suche.Signals & Reaktivität
  • 03Listen: suchen, filtern, sortieren, blätternEine Kette von computed-Signals, die nur neu berechnet, was sich geändert hat — mit den Filtern in der URL, damit ein Link dieselbe Ansicht öffnet.Signals & Reaktivität
  • 03Observables von null anWas ein Observable ist, subscribe und unsubscribe, die Operatoren, die du jede Woche brauchst, cold vs. hot — und wann ein Signal reicht.Signals & Reaktivität
  • 03Signals ↔ RxJStoSignal, toObservable, takeUntilDestroyed, outputFromObservable — und wann RxJS weiterhin die richtige Wahl bleibt.Signals & Reaktivität
  • 04input() und output()Inputs als Signals (required, transform, alias) und typisierte Outputs. Daten nach unten, Events nach oben.Komponenten: Kommunikation
  • 04model() — Two-Way-BindingBanana-in-a-Box [( )] mit einer einzigen API. Wann du es nutzt und wann input + output besser ist.Komponenten: Kommunikation
  • 04viewChild & contentChildQueries als Signals: viewChild, viewChildren, contentChild, contentChildren, die Option read.Komponenten: Kommunikation
  • 04Lifecycle & DestroyRefWelche Hooks in der Signals-Ära noch zählen, afterNextRender, DestroyRef und typisiertes ngOnChanges.Komponenten: Kommunikation
  • 04Content Projectionng-content mit select, mehrere Slots, Standardinhalt und die Falle der bedingten Projektion.Komponenten: Kommunikation
  • 04ng-template & ngTemplateOutletTemplates als Werte: Render Props in Angular, typisierter Kontext und Anpassen von Komponenten.Komponenten: Kommunikation
  • 05Smart vs. DumbContainer vs. Presentational: wer den Zustand hält, wer nur anzeigt und wie du die beiden sauber trennst.Komponenten-Design
  • 05Generische Komponenten <T>Eine korrekt typisierte DataTable<T> oder Select<T>, mit Templates für Zellen.Komponenten-Design
  • 05Dynamische KomponentenNgComponentOutlet, createComponent mit inputBinding/outputBinding und ein Dashboard, das aus einer Konfiguration gebaut wird.Komponenten-Design
  • 05Direktiven & Host-KompositionAttribut-Direktiven, die host: {}-Metadaten und die Directive Composition API (hostDirectives).Komponenten-Design
  • 05Eigene Formular-ControlsFormValueControl (Signal Forms) vs. ControlValueAccessor: eine Sternebewertung, in beiden Varianten.Komponenten-Design
  • 05Change DetectionOnPush ist ab v22 der Standard, zone.js entfällt ab v21. Was das Rendering auslöst und wie du dir nicht die Finger verbrennst.Komponenten-Design
  • 06inject() & @Service()Der neue @Service()-Decorator ab v22, inject() vs. Konstruktor und der Injection-Kontext.Dependency Injection
  • 06Provider & die Injector-HierarchieRoot vs. Route vs. Komponente, useClass/useValue/useFactory/useExisting und die Modifier optional/self/skipSelf.Dependency Injection
  • 06InjectionToken & provideX()Typisierte Konfiguration, provideFeature()-Funktionen, makeEnvironmentProviders und Initializer.Dependency Injection
  • 06injectAsync() — Lazy ServicesLade einen schweren Service erst, wenn du ihn brauchst, mit Prefetch im Leerlauf.Dependency Injection
  • 07Ordnerstrukturcore / shared / features, was in welchen Ordner gehört und wie ein Feature von innen aussieht.Architektur der Anwendung
  • 07Shared vs. FeatureWann du eine Komponente nach Shared verschiebst und (vor allem) wann NICHT. Eine konkrete Checkliste.Architektur der Anwendung
  • 07Interfaces & ModelleInline-Interface oder eigene Datei? DTO vs. Domänenmodell, type vs. interface, wohin damit.Architektur der Anwendung
  • 07State Management mit SignalsEinfache Signal-Stores, Fassaden, lokaler vs. globaler Zustand und wann du NgRx brauchst.Architektur der Anwendung
  • 07Styleguide & NamensgebungDie aktuellen offiziellen Konventionen: Dateinamen ohne Suffixe, protected, readonly, Reihenfolge der Member.Architektur der Anwendung
  • 07Barrels, Aliase & Grenzenindex.ts, Pfad-Aliase, die öffentliche API eines Features und Abhängigkeitsregeln, die sich automatisch prüfen lassen.Architektur der Anwendung
  • 07Fehler: @boundary & ErrorHandlerDer neue @boundary-Block ab v22.2, der globale ErrorHandler, HTTP-Fehler und Fehler aus resource.Architektur der Anwendung
  • 08Modernes Routing & Lazy LoadingloadComponent, Child Routes, Parameter als Inputs und Parameter-Vererbung (neuer Standard in v22).Routing
  • 08Guards & ResolvercanActivate, canMatch, canDeactivate und resolve als Funktionen, mit Redirects über UrlTree / RedirectCommand.Routing
  • 09Signal Forms — die GrundlagenFormulare auf Basis von Signals: form(), [formField], schemabasierte Validierung. Stabil seit v22.Formulare
  • 09Signal Forms — fortgeschrittenEigene und feldübergreifende Validierung, async/HTTP mit Debounce, dynamische Listen, disabled/hidden, wiederverwendbare Schemas.Formulare
  • 09Typisierte Reactive FormsTypisierte FormGroup, nonNullable, FormArray — und wie sie neben Signal Forms bestehen.Formulare
  • 10HttpClient, Interceptors & die API-SchichtHttpClient ohne Setup (v21), Fetch als Standard (v22), funktionale Interceptors und eine API-Schicht mit DTO-Mapping.HTTP & Daten
  • 11Performance — eine ChecklisteWas wirklich zählt: OnPush + Signals, track, @defer, Lazy Routes, Bilder, Bundles und Hydration.Qualität & Performance
  • 11Testen mit VitestVitest ist ab v21 der Standard-Runner. TestBed, Komponenten mit Signals, Services, HTTP und Harnesses.Qualität & Performance
  • 11DevTools: ein Blick in deine AppChrome DevTools und Angular DevTools Schritt für Schritt: was jedes Panel zeigt, mit Übungen, die auf dieser Website funktionieren.Qualität & Performance
  • 11Angular AriaHeadless, barrierefreie Komponenten, die du nach Belieben stylst: Tabs, Accordion, Menü, Listbox...Qualität & Performance
  • 12SSR, Prerendering & Render ModesWann auf dem Server gerendert wird, wann beim Build und wann nur im Browser: RenderMode pro Route, app.routes.server.ts und die echten Kosten.SSR & Hydration
  • 12Hydration: Event Replay & inkrementellWie der Browser das Server-HTML übernimmt, ohne es neu zu rendern: vollständige Hydration, Event Replay, @defer (hydrate on …) und Mismatch-Fehler.SSR & Hydration
  • 12Servertauglicher Codewindow gibt es auf dem Server nicht: PLATFORM_ID, afterNextRender, DOCUMENT, TransferState, der HTTP-Cache und PendingTasks.SSR & Hydration
  • 13Micro FrontendsWann es sich lohnt, eine App in mehrere Deployments aufzuteilen und wann es nur Komplexität ist: Native Federation, Module Federation, iframes, Web Components.Architektur im großen Maßstab
  • 13Web Components mit Angular ElementscreateCustomElement: eine Angular-Komponente, die überall als HTML-Tag nutzbar ist, plus Kommunikation zwischen Apps über Events und BroadcastChannel.Architektur im großen Maßstab
  • 13Monorepo, Bibliotheken & GrenzenEin Workspace mit mehreren Apps und Bibliotheken: ng generate library, Nx, Secondary Entry Points, Publishing und Abhängigkeitsregeln.Architektur im großen Maßstab
  • 13Hexagonale Architektur (Ports & Adapters)Eine Domäne ohne Angular, Ports als abstrakte Klassen und austauschbare Adapter: HTTP, localStorage oder In-Memory, ohne die UI anzufassen.Architektur im großen Maßstab
  • 14Signals unter der HaubeDer reaktive Graph: Producer und Consumer, Push-Pull, warum computed lazy und glitch-frei ist, das Diamond-Problem und wann Effects laufen.Fortgeschrittene Reaktivität
  • 14Fortgeschrittenes RxJS: Operatoren höherer OrdnungswitchMap, mergeMap, concatMap und exhaustMap an einem Live-Diagramm, dazu Retry mit Backoff, shareReplay und wie du Leaks vermeidest.Fortgeschrittene Reaktivität
  • 14NgRx SignalStoreState Management im großen Stil auf Signals: withState, withComputed, withMethods, rxMethod, Entities und Hooks — und wann ein einfacher Store reicht.Fortgeschrittene Reaktivität
  • 14Zustandsautomaten mit SignalsKeine unmöglichen Zustände mehr: ein typisierter Automat auf Signals, mit Übergängen, Guards und einem Live-Zustandsdiagramm.Fortgeschrittene Reaktivität
  • 15WebSockets: Echtzeit, die das Netz überstehtEin typisierter Socket als Signals: Reconnect mit Backoff und Jitter, Heartbeat, ein Postausgang im Offline-Modus und SSR-Sicherheit.Echtzeit & offline
  • 15Optimistische Updates & RollbackEine sofortige UI, die ehrlich bleibt: Snapshot und Rollback, Antworten in falscher Reihenfolge, Idempotenzschlüssel.Echtzeit & offline
  • 15Offline-first: Service Worker & CachingDer Angular Service Worker: Caching-Strategien, Update-Hinweise und ein Postausgang für Änderungen, die offline entstehen.Echtzeit & offline
  • 16Web WorkersSchwere Berechnungen, ohne die UI zu blockieren: ein echter Worker in der Seite, Message Passing und wann es sich nicht lohnt.Fortgeschrittene UI & Performance
  • 16Riesige Listen: Virtual Scroll100.000 Zeilen ohne Ruckeln: CDK Virtual Scroll, itemSize, trackBy und die Alternativen (Paginierung, Infinite Scroll).Fortgeschrittene UI & Performance
  • 16Moderne Animationen & View Transitionsanimate.enter und animate.leave statt des veralteten @angular/animations, CSS-Transitions und View Transitions bei der Navigation.Fortgeschrittene UI & Performance
  • 16Memory Leaks finden und behebenSubscriptions, Timer und Listener, die ihre Komponente überleben – wie du sie in den DevTools findest und schließt.Fortgeschrittene UI & Performance
  • 17Sicherheit: XSS, Sanitizing & CSPWas Angular automatisch gegen XSS tut, wann bypassSecurityTrust gefährlich wird, dazu CSP mit Nonce, Trusted Types und XSRF.Sicherheit & Globalisierung
  • 17Authentifizierung: Tokens & RefreshEin Interceptor, der das Token anhängt, bei 401 einmal erneuert und die wartenden Requests wiederholt — dazu, wo du das Token aufbewahrst.Sicherheit & Globalisierung
  • 17OAuth 2.1 & OpenID Connect mit PKCEDer Authorization-Code-Flow mit PKCE Schritt für Schritt: Verifier und Challenge, State und Nonce, das ID-Token und warum ein BFF sicherer ist.Sicherheit & Globalisierung
  • 17Internationalisierung (i18n)$localize, das i18n-Attribut, ICU plural/select, ein Build pro Sprache vs. Übersetzungen zur Laufzeit und Formatierung nach Locale.Sicherheit & Globalisierung