2013-03-26 4 views
24

У меня есть приложение AngularJS со страничной сеткой (два вложенных ng-repeat). На одной странице имеется примерно 25x40 элементов ввода. В начале, который сделал 1000 привязок, производительность пейджинга была приемлемой.Как ускорить приложение AngularJS?

Но тогда сложность страницы растет: динамические классы, различные контекстные меню, условный контент для каждой ячейки сетки. И с оценкой 6000 привязок (6 на элемент ввода) пейджинг стал непригодным для медленного использования.

Мой вопрос: как я вообще подхожу к проблемам производительности в AngularJS? Очевидным первым шагом является измерение. Но результаты Chrome Profiler не говорят мне об этом, далеко не зная, как действовать.

Self  Total       Function 
----------------------------------------------------------------- 
24 ms 2.79 s angular.js:7997   Scope.$digest 
1 ms  1 ms controllers.js:365  setViewportData 
16 ms  692 ms angular.js:13968  ngRepeatWatch 
8 ms  22 ms angular.js:6439   extend.literal 
9 ms 1.22 s angular.js:14268  ngSwitchWatchAction 
16 ms  45 ms angular.js:12436  ngModelWatch 
0  621 ms angular-ui-4.0.js:264 initDateWidget 
0   13 ms angular.js:12859  ngClassWatchAction 
0   70 ms angular.js:14184  ngStyleWatchAction 
1 ms  5 ms angular-ui-4.0.js:261 getOptions 
0   16 ms angular.js:579   copy 
0   1 ms angular.js:4558   interpolateFnWatchAction 
1 ms  2 ms angular.js:5981   token.fn.extend.assign 
0   37 ms angular.js:8151   Scope.$eval 
1 ms  1 ms angular.js:6137   extend.constant 
14 ms  16 ms angular.js:651   equals 
1 ms  1 ms angular.js:4939   $interpolate.fn 

стороне: есть ли шанс, что 'Object.observe() ускорит вещи в будущем (не обращая внимания «initDateWidget», что, очевидно, другая тема)?

+0

Я работал над этим вопросом здесь, чтобы помочь людям ускорить NG2 приложения, он должен быть в состоянии предоставить вам некоторые идеи: https: // StackOverflow. com/questions/42583421/how-to-compress-and-optimize-an-angular2-application – HappyCoder

ответ

27

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

Я знаю, что это уродство, но Angular не предназначено для установки более 3000 привязок. Поскольку он делает дайджест, и это не шаблон наблюдателя, он действительно замедляет работу, поэтому многие настроены.

Вы можете использовать гибридный подход, в котором вы все еще использовали ng-repeat, но все значения были помещены в DOM с прямой манипуляцией DOM из пользовательской директивы, что позволило избежать всех привязок.

20

Если вы этого еще не сделали, установите модуль AngularJS Chrome Batarang, который поможет вам определить, какое из ваших привязок вызывает у вас горе. https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk?hl=en

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

Компонент ng-grid реализует это и может стоить взглянуть на то, чтобы использовать его напрямую или украсть технику. http://angular-ui.github.com/ng-grid/

+0

Какой замечательный инструмент! Спасибо, спасибо, спасибо! Это должно быть установлено на каждом компьютере разработчика ;-) – Sebastian

+0

Хороший инструмент, но все же он показывает мне, что ngModelWatch занимает 91,9% от общего времени, поэтому действительно точное определение трудно, возможно, я использую его неправильно – Highmastdon

13

Немного поздно, но может быть, это работает для вас:

https://github.com/Pasvaz/bindonce

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

18

Ресурс

This post about angularJS performance on large lists имеет хороший обзор вариантов у вас есть для настройки производительности.

Выше ответы (кроме плагина Batarang) также упоминаются в пределах. Это всего лишь обзор советов в этой статье.

Сократить данные с limitTo (постраничной)

Одним из наиболее очевидных решений является сокращение количества привязок за счет уменьшения количества элементов в вашем представлении.Разбиение данных может быть выполнено с помощью фильтра limitTo по адресу ng-repeat.

Пример: How to improve performance of ngRepeat over a huge dataset (angular.js)? Эта статья также содержит a jsbin example.

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

<li ng-repeat="item in filteredItems()"> // Bad idea, since very often evaluated. 
<li ng-repeat="item in items"> // Way to go! 

Удалить привязки с bindonce

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

Решение bindonce решение намного больше, чем просто удаление двухстороннего связывания. В основном он ожидает, что значение будет привязано один раз до удаления привязки. Лучше всего читайте сами. Проверьте the bindonce project для деталей.

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

Использование нг сетки

Ng-grid имеет то преимущество, что только визуализирует те элементы, которые в настоящее время видны. Читайте больше на http://angular-ui.github.io/ng-grid/.

Аналогичные ng-if полностью удаляют скрытые элементы из дерева DOM, а ng-show только удерживает их на месте, но скрыт. Примите во внимание, что ng-if поместит копию оригинала (оригинал - это ключ, а не изменения, который есть), на месте, когда он снова показан.

Советы для фильтрации

В статье также есть некоторые большие подсказки для фильтрации списков.

Как с помощью ng-show, чтобы скрыть отфильтрованные элементы, так как этот способ не должен создаваться подписок.

И еще один метод, называемый «debounce user input». Последняя опция - подождать с фильтрацией, пока пользователь не перестанет печатать. В том числе a jsfiddle example.

Больше

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

Еще одна приятная рецензия является How does data binding work in AngularJS?

6

В угловом 1.3 и многое другое вы можете связать один раз не используя :: нет необходимости использовать другие 3 партия JS

<li ng-repeat="item in :: items"> 

Это хорошо, если элементы не изменится поэтому вы можете связать их один раз

1

я столкнулся проблемы с производительностью, когда количество слушателей exceded 1000+ в компоненте сетки данных.

Я решил эти проблемы, используя директиву, которая строит мое представление с помощью response.js. директива выставила функцию обновления.

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

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

В конечном итоге я прекратил использование angular.js и перешел на response.js + FLUX. я думаю, что это лучше, но я знаю, что его нелегко переложить с углового, но это того стоит.

Angular directive that uses react.js

0

У меня были проблемы с производительностью нг-сеткой с большими данными, она была решена путем замены его Angular Grid. Демонстрация на своем веб-сайте показывает, что он легко управляет 100 000 строк.

0

Я боролся с этим в течение нескольких недель. Я обнаружил, что две вещи имеют существенную разницу:

(i) ОДИН РАЗ: используйте одноразовые привязки, где вы можете; и (ii) DEBOUNCE: для ввода, который мне не нужен, сразу же размножается, но может ждать 250 мс, установите настройку debounce. Это сделало НЕВЕРОЯТНОЕ отличие от моей большой таблицы ng-repeat. Я не могу подчеркнуть, насколько эффективна настройка debounce. (см. здесь: https://docs.angularjs.org/api/ng/directive/ngModelOptions)

0

bject.observe() - предлагаемый механизм для передачи истинной привязки данных к браузеру. Он предоставляет механизм наблюдения за изменениями объектов и массивов, уведомляя других о мутациях, сделанных этими объектами.

<!DOCTYPE html> 
<html> 
<head> 
<base target="_blank"> 
<title>Object.observe()</title> 

<link rel="stylesheet" href="../css/main.css" /> 

</head> 

<body> 

<div id="container"> 

    <h1><a href="https://shailendrapathakbits.wordpress.com/" title="code_lab_by_shail ">code_lab_by_shail</a> Object.observe()</h1> 

    <p>An object <code>o</code> is created and <code>Object.observe()</code> is called on it.</p> 

    <p>Three changes are made to <code>o</code> and <code>Object.observe()</code> records these changes as shown below.</p> 

    <p>Use the console to find out what happens if you make further changes to <code>o</code>: it's defined in global scope.</p> 

    <p>Call <code>Object.unobserve(o, observer)</code> to stop observing changes.</p> 

    <p id="data" style="font-size: 14px;"></p> 

    <script src="js/main.js"></script> 

    <a href="https://github.com/shailendra9/objectobserver/blob/master/index.html" title="View source for this page on GitHub" id="viewSource">View source on GitHub</a> 

</div> 

<script src="../js/lib/ga.js"></script> 

</body> 
</html>