High Level

At a high level, there are two major pieces to the Angular Universal:

  1. Rendering on the server which means generating all the HTML for a page at a given route
  2. Transitioning from the server view to the client view in the browser client

There are two different approaches you can use for server rendering. The first option is to pre-render your application which means that you would use one of the Universal build tools (i.e. gulp, grunt, broccoli, webpack, etc.) to generate static HTML for all your routes at build time. Then you could deploy that static HTML to a CDN. The advantage of this approach is that it is highly scalable and performant. The disadvantage is that it is not quite as flexible as the second approach.

The second approach is to dynamically re-render your application on a web server for each request. There are still several caching options available with this approach to improve scalability and performance, but you would be running your application code within the context of Angular Universal for each request.

Angular Universal was originally built to work with a node.js back-end. There are adapters for most popular node.js server-side frameworks such as Express or Hapi.js. In addition to node.js, however, Angular Universal has ASP.NET Core support. In the near future we hope to add support for Java, PHP and Python.

Server Rendering Flows

Flow for server pre-rendering:

  1. Generate static HTML with build tool
  2. Deploy generated HTML to a CDN
  3. Server view served up by CDN
  4. Server view to client view transition (see below)

Flow for server re-rendering:

  1. HTTP GET request sent to the server
  2. Server generates a page that contains rendered HTML and inline JavaScript for Preboot (and you can optionally add serialized data for caching purposes)
  3. Server view to client view transition (see below)

Flow for server view to client view transition:

  1. Browser receives initial payload from server
  2. User sees server view
  3. Preboot creates hidden div that will be used for client bootstrap and starts recording events
  4. Browser makes async requests for additional assets (i.e. images, JS, CSS, etc.)
  5. Once external resources loaded, Angular client bootstrapping begins
  6. Client view rendered to the hidden div created by Preboot
  7. Bootstrap complete, so Angular client calls preboot.done()
  8. Preboot events replayed in order to adjust the application state to reflect changes made by the user before Angular bootstrapped (i.e. typing in textbox, clicking button, etc.)
  9. Preboot switches the hidden client view div for the visible server view div
  10. Finally, Preboot performs some cleanup on the visible client view including setting focus

Note that much of this is configurable and can be adjusted for your use case. For example, you can control exactly how Preboot listens for events, replays them and switches from server to client view. There are also several options for performance optimizations.