Как мне измерить производительность цикла дайджеста моего приложения AngularJS?


82

Каков простой способ измерить продолжительность цикла дайджеста angularjs? Существуют различные методы анализа производительности цикла дайджеста, но каждый имеет свои собственные ловушки:

  • Профилировщик Chrome: слишком много деталей, не разбивает цикл дайджеста таким образом, чтобы его было легко найти.
  • Batarang (плагин для браузера AngularJS): слишком много накладных расходов, низкая частота обновления, взрывается с большими приложениями.

... должен быть способ получше?! 1?

Ответы:


148

Вот секрет. В инструментах Chrome dev выполните запуск профиля процессора. После того, как вы остановили захват, внизу экрана появится треугольник вниз рядом с надписью «Heavy (Bottom Up)». Щелкните треугольник и выберите «Таблица пламени». Находясь в режиме Flame Chart, вы можете масштабировать и панорамировать, чтобы увидеть циклы дайджеста, сколько времени они занимают и какие именно функции вызываются. Таблица Flame невероятно полезна для отслеживания проблем с загрузкой страниц, проблем с производительностью ng-repeat, проблем цикла дайджеста! Я действительно не знаю, как я смог отлаживать и профилировать до Flame Chart. Вот пример:

Таблица пламени в инструментах разработчика Chrome


10
Благодарю. Просто попробовал, и это кажется очень полезным. Можете ли вы опубликовать короткое демонстрационное видео о том, как вы можете использовать его на сайте для обнаружения и устранения проблем с производительностью? Было бы очень интересно. Еще раз спасибо.
Соферио

3
Кажется, это просто называется "диаграммой" и выглядит немного иначе в текущей (v. 51.0) версии Chrome.
Марк Стобер,

Google выпустил подробное руководство с короткими видеороликами: developers.google.com/web/tools/chrome-devtools/…
Vaiden

41

Следующий ответ расскажет вам о производительности цикла $ digest в режиме ожидания , т. Е. О производительности дайджеста, когда ни одно из ваших контрольных выражений не изменится. Это полезно, если ваше приложение кажется вялым, даже если представление не меняется. Для более сложных ситуаций см. Ответ aet.


Введите в консоль следующее:

angular.element(document).injector().invoke(function($rootScope) { 
  var a = performance.now(); 
  $rootScope.$apply(); 
  console.log(performance.now()-a); 
})

Результат даст вам продолжительность цикла дайджеста в миллисекундах. Чем меньше число, тем лучше.


ЗАМЕТКА:

Доми отметил в комментариях: angular.element(document) мало что даст, если использовать ng-appдирективу для инициализации. В этом случае ng-appвместо этого возьмите элемент. Например, делаяangular.element('#ng-app')

Вы также можете попробовать:

angular.element(document.querySelector('[ng-app]')).injector().invoke(function($rootScope) { 
  var a = performance.now(); 
  $rootScope.$apply(); 
  console.log(performance.now()-a); 
})

В этом случае ничего не меняется, поэтому никакие наблюдатели не запускаются, ничего не переоценивается и т. Д. Вы не получаете «реальных» чисел.
Лучше Оливер

2
Конечно, это «настоящие» числа. Вы ошибаетесь, выполняя $ rootScope. $ Apply () повторно оценивает всех ваших наблюдателей, чтобы узнать, изменились ли они (иначе как angular узнает, что ничего не изменилось?).
Gil Birman

Может быть , мы имеем в виду что - то другое, так что я просто цитирую документы: The listener is called only when the value from the current watchExpression and the previous call to watchExpression are not equal. Ваш код не принимает во внимание слушателей. А angular привлекает множество слушателей. Вы бы никогда не позвонили, $apply()если ничего не изменилось, поэтому ваши результаты рассказывают только половину истории. В зависимости от обстоятельств он может быть менее интересным;)
a better oliver

1
Представьте себе: у вас есть 1000 контрольных выражений, все они будут оценены, но в результате сработает один «слушатель». Вас больше беспокоит качество выражения часов или слушатели?
Гил Бирман

1
angular.element(document)мало что даст, если вы использовали ng-appдирективу для инициализации. В этом случае ng-appвместо этого возьмите элемент. Например, делая angular.element('#ng-app')...
Доми


14

Вы также можете использовать angular-performance

Это расширение предоставляет в реальном времени графики мониторинга количества наблюдателей, времени дайджеста и скорости дайджеста. Вы также получаете распределение времени дайджеста, чтобы можно было выделить исключительно длительное время дайджеста из более рекурсивных паттернов, и все данные в реальном времени связаны с событиями, чтобы вы могли определить, какие действия изменили производительность приложения. Наконец, вы можете рассчитать время для методов сервисов и подсчитать их выполнение, чтобы определить те из них, которые больше влияют на время работы вашего приложения.

Снимок экрана производительности Angular

Заявление об отказе: я являюсь автором расширения


Я его установил, но пока не понял, как им пользоваться. Ваше расширение добавило функции в профилировщик Chrome? Благодарю.
gm2008

Когда вы открываете инструменты разработчика, у вас должна быть вкладка «Angular» с этим представлением.
Николас Джозеф

Спасибо за ответ. Для успешной сборки расширения мне также необходимо установить Python, VCBuild.exe, Windows SDK. Может быть, вы могли бы добавить в свое руководство.
GM2008 08

У меня Mac OsX, поэтому я понятия не имею, что нужно для Windows. Возможно, вы могли бы сделать запрос на перенос в репо, чтобы описать, что вы сделали. Спасибо за информацию !
Николас Джозеф

что делает "Function Timing"? Я ввел имена модулей, но вроде ничего не происходит.
Раоэль

5

Один удобный инструмент для отслеживания цикла дайджеста можно найти с помощью отличного инструмента ng-stats от @kentcdodds . Он создает такой небольшой визуальный элемент, который может быть реализован даже через букмарклет. Его даже можно использовать внутри iFrames, например jsfiddle.

хороший цикл переваривания введите описание изображения здесь

Маленькая утилита для отображения статистики об угловом дайджесте / часах вашей страницы. В настоящее время в этой библиотеке есть простой скрипт для создания диаграммы (см. Ниже). Он также создает модуль с именем, у angularStatsкоторого есть директива, angular-stats которая может использоваться для размещения статистики angular в определенном месте на указанной вами странице.

Найдено на https://github.com/kentcdodds/ng-stats


2

Вы можете использовать UX Profiler

  • Просмотр транзакций пользователя, то есть CLICK и все вызванные им действия (другие события, XHR, таймауты) сгруппированы вместе.
  • Измерения времени (по ощущениям Пользователя) всей Пользовательской транзакции и / или ее частей.
  • Комбинированная асинхронная трассировка стека.
  • Focused Profiler - профилируйте только проблемное событие.
  • Интеграция Angular 1.x.

введите описание изображения здесь


1

для строгого режима, один запуск дайджеста cucle, запустите его в консоли f12 в chrome

angular.element(document).injector().invoke(['$rootScope',function($rootScope) { var a = performance.now(); $rootScope.$apply(); return performance.now()-a; }])

0

описанные выше инструменты уже дали вам представление об измерении производительности цикла дайджеста. Наиболее важными моментами для повышения производительности цикла дайджеста являются:

  • Внимательно отслеживайте события прокрутки, чтобы скрыть все невидимые элементы и
    значительно сократить количество наблюдателей.

  • Иметь управляемые циклы дайджеста для всех остальных событий.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.