Подтвердить что ты не робот

Angular JS Scaling & Performance

Мы пытаемся решить проблемы производительности с помощью приложения Angular, которое мы создаем для банка.

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

Структура приложений:

  • По существу, гигантская многоформатная страница.
  • Каждая форма является ее собственной частичной, с вложенными контроллерами и частицами, имеющими глубину в 3 уровня.
  • Те же формы повторяются ng по набору json-объектов.
  • Каждая форма привязана к объекту/модели, которая повторяется.
  • Мы должны поддерживать где угодно от 1-200 форм на странице.

Если вы посмотрите на график. Мы проводим много времени в методе jQuery parse html, jQuery пересчитываем метод stye, GC Event (Garbage Collection). Я предполагаю, что сведение к минимуму должно ускорить процесс. Все они являются частью жизненного цикла Angular, но могут быть лучшие способы избежать их. Вот несколько скриншотов профайлера:

Recalculate StyleGC Event

В конечном счете, приложение вяло, так как количество повторяющихся форм выше 5. Каждая форма относительно не связана с другими. Мы старались не смотреть какие-либо общие свойства между формами.

4b9b3361

Ответ 1

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

https://gist.github.com/btm1/6802599

https://gist.github.com/btm1/6802312

https://gist.github.com/btm1/6746150

Один из ответов выше говорит о том, что ng-repeat имеет огромные образы производительности, поэтому я даю вам "set-repeat" однократную директиву привязки данных:)

Ответ 2

Трудно предоставить решение без дополнительной информации о вашей проблеме, но я недавно испытал (и решил) проблему производительности, которая может быть похожим на то, что вы видели, и не было связано с циклом $digest.

Большинство обсуждений производительности angularjs, которые вы найдете (в том числе отличный пост от Misko), касаются производительности грязной проверки и цикла $digest. Но это не единственная проблема с производительностью, с которой вы можете столкнуться с angularjs. Первый шаг должен состоять в том, чтобы определить, является ли цикл дайджеста вашей проблемой или нет. Для этого вы можете использовать batarang или просто посмотреть на свое приложение и на то, когда оно точно вяло. Когда цикл дайджеста медленный, практически любое взаимодействие с пользовательским интерфейсом будет медленным.

OTOH, у вас может быть приложение с быстрым циклом дайджеста, которое замедляется только при загрузке, переключении представлений или в противном случае изменении наборов компонентов для отображения, и это может проявляться в профилировании, поскольку много времени, затрачиваемого на парсинг HTML и сбор мусора. В моем случае это было решено путем выполнения некоторых предварительных вычислений html-шаблона для отображения вместо того, чтобы полагаться на ng-repeat, ng-switch, ng-if всюду.

Я использовал виджет ng-repeat = "в виджетах", содержащий ng-переключатель типа виджета, чтобы отобразить произвольный набор виджетов (настраиваемые автономные директивы). Заменив это кодом на создание шаблона angular для определенного набора виджетов, ускоренное переключение маршрутов с ~ 10 секунд до практически мгновенного.

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

Ответ 3

Как правило, AngularJS будет работать плохо, если активны более 2000 привязок данных, т.е. 2000 элементов в области, которые проверяются грязью каждый цикл $digest. Из-за этого Ng-repeat имеет большое влияние на производительность; каждый повторяющийся элемент устанавливает не менее двух привязок, не считая каких-либо дополнительных данных или директив, которые используются внутри элемента.

Один из разработчиков за AngularJS дает отличное описание деталей грязной проверки и ее производительность в этом SO-ответе:

fooobar.com/questions/580/...

Нить комментария ниже этого ответа стоит прочитать, и я также расскажу о некоторых мыслях об этом в ответе ниже на той же странице:

fooobar.com/questions/580/...

Ответ 4

Для повышения производительности в производстве читайте очень красивый однострочный снимок ниже:

Цитирование документации AngularJS:

По умолчанию AngularJS связывает информацию о привязке и областям с узлами DOM и добавляет классы CSS к элементам, привязанным к данным:

В результате ngBind, ngBindHtml или {{...}} интерполяции, привязки данных и CSS-ng-привязки привязаны к соответствующему элементу.

В тех случаях, когда компилятор создал новую область действия, к соответствующему элементу присоединяются область видимости и класс CSS ng-scope или ng-isol-scope. Эти ссылки области могут быть доступны через element.scope() и element.isolateScope().

Инструменты, такие как Protractor и Batarang, нуждаются в этой информации для запуска, но вы можете отключить это в производстве для значительного повышения производительности с помощью:

myApp.config(['$compileProvider', function ($compileProvider) {
  $compileProvider.debugInfoEnabled(false);
}]);

Подробнее читайте здесь

Ответ 5

Мне жаль, что я поставил его как "ответ", потому что у меня нет достаточного количества баллов, чтобы сделать комментарий.

У нас возникли аналогичные проблемы с нашим приложением AngularJS. Используя "batarang", кажется, приходится иметь дело с большим количеством объектов области видимости, а их соответствующие выражения $watch создают производительность hiccup. Это заставило нас задаться вопросом, следует ли вместо этого использовать другую структуру или что-то вроде ReactJS, чтобы заботиться о части "просмотра".

Ответ 6

попробуйте избежать следующих

  • избегайте использования ng-repeat, если у вас есть более 50 элементов в список за раз и избегать ручных часов
  • не используйте ng-click, ng-mouseenter, ng-mouseleave и т.д. события мыши вслепую, пока это не острая потребность, попытайтесь уменьшить их число, используя объект $event, а также концепции распространения событий js

  • где когда-либо возможно использовать область. $digest вместо scope. $watch, это гарантирует, что цикл дайджест выполняется только на дочерних областях

    1. попробуйте иметь вложенные области, т.е. один или два контроллера внутри одного родительского контроллера и сохранить логику многократного использования в родительском я использовал это во вложенных состояниях при использовании Ui-router (чтобы выполнить запрос, когда изменение URL было необходимо без обновления страницы).

самое главное! УДАЛИТЕ ВСЕ ФИЛЬТРЫ ИЗ HTML!

все вышеперечисленное запускает цикл дайджеста во всех областях вашего приложения, поэтому существует высокая вероятность того, что даже когда визуализированное представление angular снова выполняет неустанные циклы дайджеста

Ответ 7

Среднее расстояние между перемещением манипуляций DOM в пользовательские директивы и проблемы с часами $с большим количеством $watch - это использовать семантику "bind-once".

Это отлично подходит для данных, которые неизменны после получения данных. См. bindonce

Ответ 8

Это будет только ссылка! Это просто идея, которую я имел, когда я читал это, я еще не изучил это, но кто-то, вероятно, сделал это, я жду ответа на мою идею. Как об использовании общих веб-работников, чтобы получить много тяжелой обработки из потока ui? https://github.com/h2non/sharedworkers-angular-poc

Другая идея, которая у меня была, была более простой. Будет ли ваше приложение пользоваться бесконечной прокруткой? Я имею в виду, что эти формы, вероятно, не все подходят на экране, они не связаны друг с другом, так почему бы не привлечь их так, как они нужны? Загрузите их в память, затем нарисуйте их соответственно.

Ответ 9

Как и при любой другой оптимизации производительности, важно знать, как профилировать приложение, чтобы найти истинное узкое место. Тогда вы можете решить их один за другим. Я обычно сражаюсь с узкими местами в следующем порядке:

  • мой код javascript
  • angular (сложные наблюдатели и фильтры), которые запускаются в каждом цикле цикла бездействия
  • angular (ng-repeat, копирование объектов для цикла дайджеста)

Профилировал пример angular шаг за шагом, показывая, как определить узкое место на каждом шаге. http://bahmutov.calepin.co/improving-angular-web-app-performance-example.html