В моей практике самые большие проблемы с производительностью возникали из-за того, что я забывал делать отмену watch и bind событий при уничтожении директив. Нужно делать scope.$on('$destroy', function() {}); Если такие директивы попадали в большие ng-repeat браузер иногда просто умирал.
Добавлю, что у Angular есть настройка, которая по дефолту делает возможным получать scope из DOM элемента и добавляет классы типа ng-scope, ng-isolated-scope. Это может быть полезно при разработке и тестировании, но для продакш версии лучшее ее отключить, это немного улучшить перфоманс.
myApp.config(['$compileProvider', function ($compileProvider) {
$compileProvider.debugInfoEnabled(false);
}]);
Подробнее:
https://docs.angularjs.org/guide/production