Rendering cycle in Angular applications — browser, angular and zone.js interaction

Post Editor

Modern web stack involves lots of moving parts. Let's take a look at all the actors and their functions in a typical Angular application.

4 min read
0 comments
post

Rendering cycle in Angular applications — browser, angular and zone.js interaction

Modern web stack involves lots of moving parts. Let's take a look at all the actors and their functions in a typical Angular application.

post
post
4 min read
0 comments
0 comments
This article is an excerpt from my Angular deep dive course

Modern web stack involves lots of moving parts. A browser provides DOM to describe what should be rendered on the screen and API to manipulate that presentation. It runs JavaScript as a reaction to some kind of asynchronous events initiated by user actions. The JavaScript code is usually split into framework code and application code. Application code implements business logic that processes input data and updates application state. The task of a framework is to transform the application state into DOM updates. The common name for this phrase is rendering, but it has different names in different frameworks. In Angular it’s known as change detection.

In Angular change detection automatically runs after each asynchronous event. The assumption here is that most events cause application state change that needs to be reflected in the DOM and correspondingly on the screen.

For Angular to know when the application state might change, it needs to know when those events occur. This is where zone.js library comes into play. This library decorates (patches) browser platform’s API so that all asynchronous events in the browser can be intercepted. Angular binds to the hooks exposed by zone.js and uses notifications about DOM events, timeouts, AJAX/XHR, Promise etc. as a cue to run change detection.

Angular doesn’t directly interact with zone.js, but instead uses NgZone, which is a kind of a wrapper around zone.js to restrict scope of the events that Angular should be notified about (more on this in the chapter on zonejs).

Let’s go over each step using the following simple example:

<>Copy
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div class="container"> <div> <button (click)="fetchData()">Fetch data</button> <div>title: {{title}}</div> </div> </div> `, ... }) export class AppComponent { title = null; async fetchData() { const response = await fetch('http://example.com/movies.json') const todo = await response.json(); this.title = todo.title; } }

Here’s what happens when you click on the button:

  1. browser detects the click & adds an event handler to the event queue (browser)
  2. zonejs starts with zoneAwareCallback which simply runs callback registered by Angular
  3. angular executes the wrapper around the callback from a component’s template; the wrapper marks the view and all its ancestors dirty
  4. angular runs fetchData component method through the event listener registered in a component template function
  5. business logic inside fetchData application code runs network request
  6. the request is intercepted by zone.js which schedules macrotask with a browser
  7. the event is processed now, zone.js triggers onMicrotaskEmpty through NgZone
  8. angular reacts by running application wide change detection through ApplicationRef.tick
  9. change detection updates the DOM and runs other side effects

At this point JavaScript yields control to the browser.

The event has been processed, business logic updated application state and Angular updated DOM during change detection. Time for the browser to render the updates on the screen and go on to execute the macrotask related to the nework request.

The browser updates the screen by going through the regular pipeline:

  • [Rendering] Style calculations. This is the process of figuring out which CSS rules apply to which elements based on matching selectors, for example, .headline or .nav > .nav__item. From there, once rules are known, they are applied and the final styles for each element are calculated.
  • [Rendering] Layout. Once the browser knows which rules apply to an element it can begin to calculate how much space it takes up and where it is on screen. The web’s layout model means that one element can affect others, for example the width of the <body> element typically affects its children’s widths and so on all the way up and down the tree, so the process can be quite involved for the browser.
  • [Painting] Paint. Painting is the process of filling in pixels. It involves drawing out text, colors, images, borders, and shadows, essentially every visual part of the elements. The drawing is typically done onto multiple surfaces, often called layers.
  • [Painting] Compositing. Since the parts of the page were drawn into potentially multiple layers they need to be drawn to the screen in the correct order so that the page renders correctly. This is especially important for elements that overlap another, since a mistake could result in one element appearing over the top of another incorrectly.

You can read more about it here.

This diagram describes the interaction between the actors mentioned above.

Content imageContent image

You can clearly see the operations described above using Chrome Dev Tools profiler. Here’s the callstack for the click handler:

Content imageContent image

And here are browser tasks after JavaScript yields to the browser:

Content imageContent image

For more in depth stuff like what you read above check out the course

Content imageContent image

If you believe something important is missing here do let me know in the comments!

Content imageContent image
in depth knowledge we trust

Comments (0)

Be the first to leave a comment

Share

About the author

author_image

Max is a self-taught software engineer that believes in fundamental knowledge and hardcore learning. He’s the founder of inDepth.dev community and one of the top users on StackOverflow (70k rep).

author_image

About the author

Max Koretskyi

Max is a self-taught software engineer that believes in fundamental knowledge and hardcore learning. He’s the founder of inDepth.dev community and one of the top users on StackOverflow (70k rep).

About the author

author_image

Max is a self-taught software engineer that believes in fundamental knowledge and hardcore learning. He’s the founder of inDepth.dev community and one of the top users on StackOverflow (70k rep).

Looking for a JS job?
Job logo
Fullstack (Angular, Node.js) Developer

Nextian Corp.

Worldwide
Remote
$84k - $107k
Job logo
Application Developer (Angular)

Karsun Solutions, LLC

Worldwide
Remote
$104k - $132k
Job logo
Angular Developer

Ryan Consulting Group

Worldwide
Remote
$77k - $80k
More jobs

Featured articles

Angularpost
17 January 202323 min read
Improve page performance and LCP with NgOptimizedImage

Explore mechanisms of NgOptimizedImage directive to improve overall page performance, targeting especially the Largest Contentful Paint (LCP) metric from Core Web Vitals. Enhance pages, make the best user experience and improve the web.