Using ReactJS with AngularJS

After releasing React in 2013, Facebook kicked off some discussions in the JavaScript community about comparing React with common libraries. Indeed, the library increases the pressure on established Frameworks because of its many modern ideas and patterns. Concepts like the implementation of a virtual DOM and the component architecture allowed programmers to create web applications which run faster and are more easily maintainable. At the same time frameworks like Angular still suffer from performance problems heating up the discussions about their concurrency.

Beside the ongoing competition between React and Angular, some people try to benefit from both technologies. The ngReact library is an example of such an approach. The Angular module allows using React as a view component inside Angular applications. Usual Angular templates can be replaced with React components which try to give you more flexibility and promise to improve the overall performance.

This blog article examines the use of the ngReact module to speed up Angular’s list rendering performance.

React.js – Virtual DOM

To quickly get some of the basics of the library and understand where React get its power from, let us start with the concept of the virtual DOM.

tree

The Virtual DOM is mainly responsible for the great performance of React applications. It restricts DOM manipulations which are seen as the main performance bottleneck for web applications. Instead of directly adjusting the browser DOM, for every single change the library creates a new Virtual DOM representation. It acts as a representative to the browser DOM and is instantiated as an ordinary JavaScript Object. To keep track of changes an algorithm compares the new Virtual DOM to the former one. The delta is passed along as a stack to the browser where the differences get rendered.

Angular—Data Binding

Now that we know how React deals with the DOM, let us take a look at Angular. The Framework uses Data Binding to synchronize between the view and the model. After the template has rendered any changes that affect the view, they get transmitted into the model and vice versa.

The state of the common data basis is held in a particular object called $scope. A $scope object gets instantiated when a single controller is attached to a DOM node and effects the scope of the controller. Therefore all $scope objects are hierarchically ordered representing the DOM hierarchy.

In addition each $scope object is set up with a $watch expression which notices the view when changes to the model are made. To realise model mutations (e.g. through the ng-click directive) Angular uses its $digest cycle to execute all registered $watch expressions beginning with the root $scope. The cycles check whether the state of the watched object has changed and trigger updates to the view. The cycle runs until no more changes are detected. Finally the browser re-renders the DOM.

Test Setup

To validate the different concepts we are going to build a simple application representing a table with 1000 rows and six columns. The example used in this blog post is based on the ngReact example from its official repository.

To verify the acceleration of Angular’s list rendering performance we first have to measure the time it takes to represent the table using Angular’s ng-repeat directive.

Therefore a two-dimensional Array is created inside the views controller and referenced via the $scope object.

The refresh method is called initially on instantiating the rows array, filling the table with new data on every page refresh. Via the ng-repeat directive the array gets referenced inside the view.

To measure the rendering performance, Chrome developer tools provides us with the timeline tool, allowing us to track every process in the rendering chain of the browser. The timeline tool shows that initially loading our app in the browser takes around 1.3 Seconds.

Loading Time Pie Chart Screenshot from Chrome Dev Tools

It’s remarkable that parsing the DOM takes nearly one second consuming the most time of all processes.

Besides the initial loading time of the app we should examine how the application performs on updating the data. Therefore we add a button that calls the refresh Method which fills the data array with new values. Next we take a another look on the developer tools, which show the total time it takes to re-render the updated values. Nearly one second passes between hitting the button and the new data being displayed.

Another pie chart of loading times

ngReact

Now let us replace our Angular template with a React component using the ngReact module. ngReact can be installed using npm or bower.

To use the ngReact module we need to include ngReacts JavaScript files as well as Reacts core libraries. The module is defined as a dependency and injected to the Angular application.

Now that ngReact is available to our application we can build a React component that renders our table data. To create a React component we call Reacts createClass method and define our markup inside the components render method. The data of the table can then be referenced via the props attribute.

With the help of the map method we transfer the two-dimensional array into HTML markup and return its Virtual DOM. To simplify the setup the DOM elements are created using React’s DOM API instead of JSX.

Finally we have to register our React component to the Angular application:

The component is inserted by referencing its name via the name attribute of the provided react-component directive.

Again, we want to consider the rendering performance of the component and compare it to the results of the former examinations. The results show that it only takes 650 ms to initially represent the table data where the process of parsing the DOM takes just nearly half of the time.

A third pie chart with loading times Another screenshot of the Chrome dev tools showing altered loading times

Now let’s compare the performance when updating the table data. We create another button to generate new values triggering the component to update the browser DOM.

A fourth pie chart with loading times

You can see that it takes roughly 500 ms from clicking the button until the table is updated with the new values. Looking at the results we see that using the React component enables us to render the content in around 50% of the time.

Further increasing the table to 2000 entries even shows us that the React component initially loaded in one third of the time.

A fifith pie chart with loading times A sixth pie chart with loading times

Results

The reason for the significantly faster rendering process is the different approaches of the two technologies trying to keep the DOM in sync. As described above Angular uses data binding to update the DOM whereas the framework registers watchers to notics changes. All registered watch expressions are handled inside the $digest cycle triggered by a certain event causing the browser to reload data after all watch expressions are checked.

Using the Chrome plugin Angular watchers you can track all watchers registered to an Angular application. The following pictures show the total number of watchers used to keep our list up to date for both applications.

results-2 results-1

With 7008 watchers our Angular app registered way more watchers than our React component, leading to a slower rendering performance of the list. The reason is that the larger amount of watchers leading to longer digest cycles, whereas the React component wins the race with just 1 watcher registered to the page.

Conclusion

So React isn’t necessarily an exclusive alternative to the Angular framework and
using React components within Angular can result in higher rendering performance.

This gives us more flexibility working on performance issues for single Angular components. In addition, developers can make use of the continually growing React community which regularly publishes ready-to-use React components.

Get in touch

Check out our web development portfolio on our website. If you have any questions use the comment section below, write an Email to info@inovex.de or call +49 721 619 021-0.

We’re hiring

Are you a web developer looking for new challenges? We’re currently hiring web front-end developers in Karlsruhe, Pforzheim, Munich, Cologne and Hamburg. Apply now or stop by and have a chat & coffee with us!

comments powered by Disqus