Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 09.10.2013, 00:02
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Angular: Performance optimization / Оптимизация производительности
Всем привет

В этой теме хотелось бы обсудить вопрос оптимизации производительности в ангуляре: как правильно писать код; чего следовало бы избегать; рецепты оптимизации производительности и т.п.

---

Ниже выжимка из всей темы

СОВЕТЫ ПО ОПТИМИЗАЦИИ ПРОИЗВОДИТЕЛЬНОСТИ

расширенное объяснение по каждому пункту можно найти почитав тему
  1. Если возможно то не слушать объекты и массивы целиком
  2. Без крайней нужды не вешать WATCH на функции
  3. Не вызывать
    $scope.$apply();
    $scope.$digest();
    
    слишком часто (например, в обработчиках событий scroll или mousemove)
  4. Не выводить в
    <element ng-repeat="..."></element>
    
    тысячи элементов, а вывести первые элементы и сделать динамическую подгрузку
  5. Если элемент скрыт с помощью ng-show или ng-hide
    <element ng-show="false"></element>
    <element ng-hide="true"></element>
    
    и внутри него есть тяжелые вычисления, вероятно, имеет смыл использовать [ng-if|ng-switch] чтобы их избежать
  6. Использовать синтаксис
    <element ng-repeat="item in array track by $index"></element> или
    <element ng-repeat="item in array track by item.id"></element>
    
    вместо
    <element ng-repeat="item in array"></element>
    
    чтобы отслеживать изменения по индексу или id, а не по значению
  7. Обновлять текущий и вложенные скопы
    $scope.$digest();
    
    а не все приложение
    $scope.$apply();
    
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 25.01.2014 в 01:39. Причина: добавлены советы
Ответить с цитированием
  #2 (permalink)  
Старый 09.10.2013, 03:14
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Я уже касался частично.

По scope.
1) Если возможно то не слушать объекты и массивы целиком. (так как ангуляру нужно выполнить цикл по всем свойствам)
2) Без крайней нужды не вешать WATCH на функции. (они будут срабатывать при любом изменении scope)
3) Подозреваю что события могут быть быстрее чем watch в ряде ситуаций, но не проверял.


По шаблону.
Мне очень интересно как ведут себя директивы помещенный внутрь ngrepeat. Не получится ли так что каждая директива внутри цикла будет пересоздаваться когда ngrepeat срабатывает повторно. Я полагаю что так оно и есть, а это означает что нужно дважды подумать прежде чем пихать директивы внутрь ngrepeat. Впрочем с несколькими сотнями итераций проблем быть не должно, конечно только если вы не обновляете данные несколько раз в секунду А вот на мобиле ХЗ сколько потянет.

Ну и просто философия.
Никто нативные операции на дум не отменял, и jQuery пока жив Если директива тяжелая по производительности, то никто не обязывает вас использовать шаблоны и связывание. Вы можете просто переписать внутренности директивы на голом JS или jQuery и получить быструю и максимально оптимизированную директиву. Ну к примеру в шаблоне директивы есть ng-show, возможно вы сумеете заменить ее нативным .style.display который однозначно сработает быстрее.
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 09.10.2013 в 04:14.
Ответить с цитированием
  #3 (permalink)  
Старый 09.10.2013, 12:21
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

DjDiablo, спасибо.

Еще у меня вот такие мысли ng-if, ng-switсh etc. как способ оптимизации производительности. Что думаете по этому поводу?

Сообщение от DjDiablo
Не получится ли так что каждая директива внутри цикла будет пересоздаваться когда ngrepeat срабатывает повторно. Я полагаю что так оно и есть
думаю, так оно и есть (судя по поведению)

Сообщение от DjDiablo
Никто нативные операции на дум не отменял, и jQuery пока жив
тогда зачем ангуляр использовать?
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 09.10.2013 в 12:35.
Ответить с цитированием
  #4 (permalink)  
Старый 09.10.2013, 12:52
Профессор
Отправить личное сообщение для DjDiablo Посмотреть профиль Найти все сообщения от DjDiablo
 
Регистрация: 04.02.2011
Сообщений: 1,815

Тест не честный чуточку . Поместив test() в ngShow ты заставил срабатывать test при любом изменении, но это не означает что срабатывает сам ngShow. Test вызывается только для того чтобы оно вернуло true или false, и ngShow получив это значение мог правильно отработать. Если бы ты слушал свойство а не функцию test то ngShow срабатывал бы только при изменении свойства. NgShowController:Controller:test и NgIfController:Controller:test не должны были оказаться в консоли если бы выводились самим ngShow .

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

Тем не менее ng-if это прикольная тема. Допустим в табах можно попробывать выключать содержимое невидимых закладок или чо нибудь в этом духе.
__________________
Лучше калымить в гандурасе чем гандурасить на колыме

Последний раз редактировалось DjDiablo, 09.10.2013 в 13:59.
Ответить с цитированием
  #5 (permalink)  
Старый 02.11.2013, 13:13
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Сообщение от DjDiablo
Тест не честный чуточку
а у меня честных тестов не бывает

Сообщение от DjDiablo
Допустим в табах можно попробывать выключать содержимое невидимых закладок или чо нибудь в этом духе.
или, например, при пагинации на клиенте или любые другие "не нужные" в данный момент куски разметки вместе с кодом

Об очевидном. Еще лучше не делать так:
element.bind( 'mousemove scroll ...', function() {
    $scope.$apply(function() { /* code here */ );
});

не вызывать пересчет скопа каждый раз в событиях, которые срабатывают достаточно часто, а по возможности использовать прокси
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
Ответить с цитированием
  #6 (permalink)  
Старый 05.11.2013, 10:32
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 557

Не выводить в ng-repeat тысячи элементов, а сделать динамическую подгрузку и выгрузку первых элементов (как чат вконтакте). Тогда и с оптимизацией директивы можно не париться)
Ответить с цитированием
  #7 (permalink)  
Старый 07.11.2013, 14:27
Новичок на форуме
Отправить личное сообщение для De-Luxis Посмотреть профиль Найти все сообщения от De-Luxis
 
Регистрация: 30.05.2009
Сообщений: 8

Сообщение от Shitbox2 Посмотреть сообщение
Не выводить в ng-repeat тысячи элементов, а сделать динамическую подгрузку и выгрузку первых элементов (как чат вконтакте). Тогда и с оптимизацией директивы можно не париться)
Ограничиваю список через фильтр. Этакий пэджинатор.
app.filter('startFrom', function() {
		return function(input, start) {
			start = parseInt(start);
			return input.slice(start);
		}
	})


И пишу в html:
<button ng-repeat="(n, button) in selectorField.items | startFrom:(currentPage - 1) * limit | limitTo:limit" ng-mousedown="setSelector(n)" ng-bind-html-unsafe="button.title"></button>


Но сотнях не тестировал, но работает шустро. Что думаете?
Ответить с цитированием
  #8 (permalink)  
Старый 09.11.2013, 18:53
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 557

Цитата:
Что думаете?
Надо потестить)

Чуть не забыл. Еще одна фишка для оптимизации.
тыц1 и тыц2.

Суть в том, что вешать события на $rootScope нужно внимательно, т. к. при удалении шаблона с контроллером корневая область видимости никуда не девается и обработчик остается.

nerv_, посмотри в своем загрузчике файлов, кажется у тебя там именно такая ситуация. Т.е. если я закрою страничку загрузки файлов, то все обработчики так и останутся на $rootScope
Ответить с цитированием
  #9 (permalink)  
Старый 09.11.2013, 21:57
Аватар для nerv_
junior
Отправить личное сообщение для nerv_ Посмотреть профиль Найти все сообщения от nerv_
 
Регистрация: 29.11.2011
Сообщений: 3,924

Сообщение от Shitbox2
nerv_, посмотри в своем загрузчике файлов, кажется у тебя там именно такая ситуация. Т.е. если я закрою страничку загрузки файлов, то все обработчики так и останутся на $rootScope
спасибо. У меня это как раз на стадии обсуждения.

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

С ui-router не работал также как и с angular route segment
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук

Последний раз редактировалось nerv_, 09.11.2013 в 22:03.
Ответить с цитированием
  #10 (permalink)  
Старый 10.11.2013, 13:24
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 557

А можно просто сделать колбеками, как у меня))

Поработай с ui-router — классная штука. Единственное, что использую от сторонних ангуляр-разработчиков) Почти всю документацию перевел
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск