TL;DR How we reduced 5000+ Angular Watchers to 300+ and still maintained Two-way Angular mapping. This is our journey, how we mixed React JS with Angular 1.4 here at Clearplan.
We love Angular -it gives us the ability to decrease time to market and still maintain an extremely beautiful Client-side codebase. A beautiful codebase is something every developer/architect/company should aim for. If you are a Saas company, this affects your bottom line - Period.
Our angular code, gives the user a powerful UI, zero wait time with asynchronous calls and live real time updating with two way UI Binding(the UI always has the latest data). This comes with an extra cost - The Watchers.
For those of you who aren’t familiar with how AngularJS does its two-way databinding, essentially you tell Angular to watch something for changes, and Angular will check it over and over. The real issue is when your web app continues to grow. For e.g. - When we started our application we had companies having a maximum of 300 markers on the map. As soon as we started adding bigger companies with 1500+ addresses, we saw our performance degrading drastically.
Performance - Why does it degrade?
We soon realized that the two way binding brings a plethora of careless inefficiencies. For every marker added on the screen, angular added a watcher- every UI update or a mouse move would trigger to refresh all the markers using filters.
The first part of optimization involved removing filters from the UI, instead we added it to the JS code and ran them based on Server sent events. This instantly gave us a huge performance but still sucked. We followed a couple of blog posts and started watching our watchers. . We added a DOM element to the left top of navbar. We did a few tweaks to our grunt file to disable this code in prod.
On the top left of the image, you can see 6K watchers
ng-repeat was sure enough the culprit, for every element in the ng-repeat it was adding a watcher. We released a micro version using A/B testing tool Optimizely with clustering to our customers and we instantly faced Rejection. So clustering was out. We looked at React JS but to migrate the then 15000 lines of code to React is a complete halt to feature development.
One Early morning - I had an idea, what if I add react to replace only the markers DOM and for the rest we continue using Angular. I took out the ng-repeat component and added the react JS component and a simple grunt react workflow. Huzzah it worked!!. All the markers still showed two way binding but we could reduce our watchers.
Currently we are able to scale to 8000-10000 Addresses.