← Back to Tutorials Chapter 15

Advanced Concepts

This chapter dives into Angular's advanced architecture: server-side rendering, the Ivy compiler, build systems, and strategies for upgrading and optimizing production applications.

Server-Side Rendering with Angular Universal

Angular Universal renders your application on the server, sending fully rendered HTML to the client. This improves SEO, social media previews, and perceived performance.

ng add @nguniversal/express-engine

This generates a server-side bundle and an Express server that handles both rendering and API requests.

platform-server

The platform-server package renders Angular applications on the server. It replaces platform-browser-dynamic in the server bundle.

// main.server.ts
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';

if (environment.production) enableProdMode();

export { AppServerModule } from './app/app.server.module';

TransferState

TransferState passes data from the server to the client to avoid re-fetching on initial load.

import { TransferState, makeStateKey } from '@angular/platform-browser';

const USERS_KEY = makeStateKey<User[]>('users');

// Server side
constructor(private state: TransferState) {}
this.http.get<User[]>('/api/users').subscribe(users => {
  this.state.set(USERS_KEY, users);
});

// Client side
const cached = this.state.get(USERS_KEY, null as any);
if (cached) {
  this.users = cached;
} else {
  // fetch from API
}
Use TransferState to eliminate the flash of loading spinners when the client re-hydrates.

Ivy Compiler

Ivy is Angular's next-generation compilation and rendering pipeline, introduced as the default in Angular 9. It produces smaller bundles, faster compilation, and improved debugging.

Compilation Modes

Angular supports two compilation modes via angularCompilerOptions:

// tsconfig.json
{
  "angularCompilerOptions": {
    "compilationMode": "full" // or "partial" for library authors
  }
}

full — Used for applications, produces fully compiled code. partial — Used for libraries, generates Angular-compatible output for consumers.

Bazel Build System

Bazel is Google's build system that handles large-scale monorepos with incremental and parallel builds. Angular libraries can be built with Bazel for faster CI pipelines.

ng new my-app --collection=@angular/bazel

Reactive Programming Patterns

Combine RxJS with Angular Signals for a powerful reactive architecture:

// Convert Observable to Signal
toSignal(this.http.get<User[]>('/api/users'));

// Combine multiple streams
const vm = computed(() => ({
  users: this.users(),
  loading: this.loading(),
  error: this.error()
}));

Backward Compatibility (ngUpgrade)

Use the @angular/upgrade package to run AngularJS (1.x) and Angular side-by-side in a hybrid application, enabling a gradual migration.

import { UpgradeModule } from '@angular/upgrade/static';

// Bootstrap AngularJS inside Angular
@NgModule({
  imports: [UpgradeModule]
})
export class AppModule {
  ngDoBootstrap() { /* handled by UpgradeModule */ }
}

Differential Loading

Angular CLI automatically generates two bundles: one for modern browsers (ES2017+) and one for legacy browsers (ES5). The browser loads the appropriate version.

<script src="runtime-es2015.js" type="module"></script>
<script src="runtime-es5.js" nomodule></script>
Angular advanced architecture
Practice Task: Add Angular Universal to an existing Angular project. Configure TransferState to pass user data from server to client. Verify that the initial page load shows content immediately without a loading spinner.