7 karma · joined November 1, 2013
You are right though that optimization #3 is a big hammer that helps reduce the need for the other optimizations, but in the end, we found using both gives us the best result. And the other optimizations which much in terms of code.
We are using version 1.1.15 and already had AngularJS re-using the pre-existing DOM elements if it could. When we tested it (without optimization #3 turned on), we found that it still had too much lag so felt it was better to use the DOM caching optimization.
We gave our optimization directive a fairly high priority so that it was guaranteed to be run first (among all the other directives on an element).
When the optimization directive ran, it just modified the scope variable passed to it, saving a reference to the original scope.$watch method and then setting scope.$watch to a new function we created. Inside that function, it does invoke the original scope.$watch.
We also had to override scope.$new to guarantee that any child elements, if they create new scopes, also create scopes with our override $watch method.
It is an interesting idea to unregister the watcher when we do not wish it to be evaluated -- thanks for the suggestion. It would force us to recreate all of the child watchers again later, when we do need them to be evaluated again. We would have to investigate the performance implications.
We are already talking about other ways we could implement these directives by only relying on the public AngularJS calls in case there is enough interest and we want to publish the directives to the community at large. They might not be as performant, but wouldn't be broken by changes in AngularJS implementation.
One twist on the optimization that we could have used but didn't was trigger the tokenization on mousedown and then the first token selection on mouseup. Testing with modern browsers shows that the newly visible div will receive the the mouseup event. And the average 100ms time between mouse down and mouse up gives us more than enough time for Angular to do the work of creating the tokens for one line.