Features, Dev Column

How we keep our user experience slick with Angular change detection and Zone.js

Jamie Burton By Jamie Burton on 7 November 2019   •   4 mins read
<span id="hs_cos_wrapper_name" class="hs_cos_wrapper hs_cos_wrapper_meta_field hs_cos_wrapper_type_text" style="" data-hs-cos-general-type="meta_field" data-hs-cos-type="text" >How we keep our user experience slick with Angular change detection and Zone.js</span>

 

In the fast world of the Instant Economy, businesses need robust, high performing platforms on which to build the next best thing for their customers. They need a reliable service - in our case payments – to get exciting new products up and running for their customers.

At Modulr we appreciate that our clients need to move at speed and that clunky user experiences waste valuable time. It does not matter how streamlined Modulr’s payment service is if the customer portal is not intuitive, easy to use or performing correctly.

And it’s important our developers test it and monitor the rendering performance of our customer portal application to provide the slickest experience frequently.

In this Dev Column, software engineer, Jamie Burton explains how and why we monitor rendering performance.


Modern browser-based applications are built with a myriad of complexities. Specifically, the browser is a very non-deterministic, often a stochastic environment in which things change.

Frameworks, such as React, Angular and Vue.js each have their own implementation of handling this complexity of changing state in application and reflecting such changes in the DOM. A short summary of change detection in Angular and React will now be discussed. I do not know enough about Vue.js to make any intelligible comments.

React

The central focus of React’s implementation of change detection is the virtual DOM and its infamous reconciliation algorithm. The virtual DOM is a tree structure and an in-memory representation of the DOM that is used to intelligently determine what changes in component state should be rendered.

This approach has several benefits, especially when used with Redux, a commonly used state management approach which uses this immutable data structure in conjunction with the virtual DOM to keep track of this state tree and render it accordingly.

So, the benefits are that time travel is possible but, and unfortunately for sci-fi fans, we mean real time travel. For example, if a user wants to press an undo button, the state tree is simply reverted to its previous state. In relation to performance, perhaps the most notable benefit is that React will not render changes in state unless it needs to, thus causing less reflows and repaints in the browser and ultimately streamlining rendering performance.

Angular

Angular’s change detection strategy is different to React. Instead of creating a virtual DOM and only rendering when needing to, Angular automatically detects every change to a components model and renders accordingly. This may seem grossly inefficient at first glance because if an application is full of state changes, then we have O(n) changes, or in other words, for every change, we re-render.

Fortunately, the Angular team has thought through their approach in more detail and changes can be manually marked for check, meaning that developers can wield this sword gracefully and only render changes when we tell it to.

However, let’s take an important step back. How is Angular aware (by default) of all state changes that occur in the application in the first place? That’s quite powerful. The answer is Zone.js, or in Angular’s case, NgZone, which is a wrapper for Zone.js within the context of Angular.

Zone.js

Zone.js is an execution context for asynchronous tasks, keeping track of what happened in a particular async function call (a zone) and associating this zone hierarchically with other zones; think of the call stack in the console, but better.

Due to its ability to keep track of these execution contexts, Angular is able to keep track of all of the changes that have occurred (within the Angular application, an important distinction) and inform its internal change detection mechanism to update the DOM accordingly.

With this in mind, it is apparent that change detection can work without Zone.js, but would have to be done manually due to Angular not being aware of such changes.

How we optimise rendering performance with Angular’s change detection

As mentioned before, optimising rendering performance with Zone.js (again, enabled by default) must take into consideration components that are state change intensive. We implement this by setting such components Change Detection Strategy to ‘OnPush’ in the component’s metadata (the @Component decorator) which deactivates change detection, then we manually mark each state change that we want to be detected with the method: this.cd.markForCheck();

Another method this.cd.detectChanges() can be used, however this will actually re-enable change detection in the component, which in many cases isn’t what needs to be done.

I do hope that this brief overview of how we use Angular and change detection to optimise rendering performance was helpful in some way.


This is one of many ways the Modulr tech team ensures our platform operates at the efficiency our clients expect and demand. Want to know more about our platform's capability? Get in touch!

To get the latest Dev Column to your inbox, sign up to the newsletter here.