- PVSM.RU - https://www.pvsm.ru -
Хотел бы поделиться небольшой заметкой о том, как ускорить выполнение $digest() путем замены стандартных директив эквивалентами, которые не вызывают $watch.
Смысл в том, что часто на странице очень много элементов для которых нужно выпонить биндинг данных только один раз используя данные моделей которые не изменяются, например:
<h1 ng-bind="l10n.main_title"></h1>
<a ng-href="/edit/{{user.id}}" ng-bind="user.name"></a>
Эти и другие стандартные директивы любезно будут проверять не изменилось ли значение выражения при каждом $digest. Исправить ситуацию можно набором довольно простых кастомных директив, например для текста:
app.directive(staticText', function() {
return {
restrict: "A"
link: function(scope, element, attrs) {
element.text(scope.$eval(attrs.customText));
}
};
})
<h1 custom-text="l10n.main_title"></h1>
Результат — минус один $watch.
Выдумывать свой велосипед конечно же не нужно, на GitHub лежат два достойных модуля:
Первый ($watch fighters) совсем простой, включает в себя такие директивы:
Второй же (Bindonce) интереснее, т.к. разработчики подумали о том, что данные для биндинга могут быть недоступны в момент рендеринга шаблона директивы (например, они подгружаются ajax-запросом). Выглядит это так:
<div bindonce="User">
<h1 bo-text="User.name"></h1>
</div>
Для родительской директивы bindonce создается времменый $watch, когда значение переданной в неё переменной становится отличным от undefined запускаются вложенные bo-* директивы, а временный $watch удаляется.
Модуль Bindonce включает:
Более подробно можно почитать на странице репозитория [2], там довольно развернутый readme.
На последок приведу функцию, которую нашел здесь [3]. Она примерно подсчитывает общее количество $watch'еров на странице.
(function () {
var root = $(document.getElementsByTagName('body'));
var watchers = [];
var f = function (element) {
if (element.data().hasOwnProperty('$scope')) {
angular.forEach(element.data().$scope.$$watchers, function (watcher) {
watchers.push(watcher);
});
}
angular.forEach(element.children(), function (childElement) {
f($(childElement));
});
};
f(root);
console.log(watchers.length);
})();
Ради интересы можно сравнить количество до и поле внедрения zero-watch директив.
Надеюсь кому то пригодится. Спасибо.
Автор: snater
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/52559
Ссылки в тексте:
[1] GitHub: https://github.com/abourget/abourget-angular
[2] GitHub: https://github.com/Pasvaz/bindonce
[3] здесь: http://stackoverflow.com/questions/18499909/how-to-count-total-number-of-watches-on-a-page
[4] Источник: http://habrahabr.ru/post/208768/
Нажмите здесь для печати.