У меня есть огромный набор данных из нескольких тысяч строк по 10 полей в каждом, около 2 МБ данных. Мне нужно отобразить это в браузере. Самый простой подход (извлекать данные, помещать их $scope
, позволять ng-repeat=""
делать свою работу) работает нормально, но он останавливает браузер примерно на полминуты, когда он начинает вставлять узлы в DOM. Как мне подойти к этой проблеме?
Одним из вариантов является добавление строк к $scope
инкрементам и ожидание ngRepeat
завершения вставки одного блока в DOM, прежде чем перейти к следующему. Но AFAIK ngRepeat не сообщает, когда завершает «повторение», так что это будет ужасно.
Другой вариант - разбить данные на сервере на страницы и извлечь их в нескольких запросах, но это еще страшнее.
Я искал документацию Angular в поисках чего-то подобного ng-repeat="data in dataset" ng-repeat-steps="500"
, но ничего не нашел. Я довольно плохо знаком с Angular способами, поэтому вполне возможно, что я упускаю суть полностью. Каковы лучшие практики в этом?
limitTo
для отображения только 20 элементов:<p ng-repeat="data in dataset | limitTo:20">{{data}}</p>
это показывает только 20 элементов. Тогда вы можете использовать страницы и показать следующие 10 элементов или что-то в этом роде. :)Ответы:
Я согласен с @ AndreM96, что лучший подход - отображать только ограниченное количество строк, быстрее и лучше UX, это можно сделать с помощью нумерации страниц или бесконечной прокрутки.
Бесконечная прокрутка с Angular действительно проста с фильтром limitTo . Вам просто нужно установить начальный лимит, и когда пользователь запрашивает дополнительные данные (я использую кнопку для простоты), вы увеличиваете лимит.
Вот JsBin .
Такой подход может быть проблемой для телефонов, потому что обычно они запаздывают при прокрутке большого количества данных, поэтому в этом случае я думаю, что нумерация страниц подходит лучше.
Для этого вам понадобится фильтр limitTo, а также пользовательский фильтр для определения начальной точки отображаемых данных.
Вот JSBin с нумерацией страниц.
источник
Самый горячий - и, возможно, самый масштабируемый - подход к преодолению этих проблем с большими наборами данных воплощен в подходе директивы collectionRepeat Ionic и других подобных реализаций. Причудливый термин для этого - «выборка окклюзии» , но вы можете суммировать его следующим образом: не ограничивайте количество отображаемых элементов DOM произвольным (но все же высоким) разбитым на страницы числом, таким как 50, 100, 500 ... вместо этого , ограничить только столько элементов, сколько пользователь может видеть .
Если вы делаете что-то вроде так называемой «бесконечной прокрутки», вы несколько уменьшаете начальное количество DOM, но оно быстро увеличивается после пары обновлений, потому что все эти новые элементы просто прикреплены внизу. Прокрутка приходит к ползанию, потому что прокрутка все о количестве элементов. В этом нет ничего бесконечного.
Принимая во внимание, что
collectionRepeat
подход состоит в том, чтобы использовать только столько элементов, сколько поместится в окне просмотра, а затем переработать их . Когда один элемент вращается вне поля зрения, он отсоединяется от дерева рендеринга, заполняется данными для нового элемента в списке, а затем снова присоединяется к дереву рендеринга на другом конце списка. Это самый быстрый из известных человеку способов получения новой информации в DOM и из нее, используя ограниченный набор существующих элементов, а не традиционный цикл создания / уничтожения ... создания / уничтожения. Используя этот подход, вы можете по-настоящему реализовать бесконечную прокрутку.Обратите внимание, что вам не нужно использовать Ionic для использования / hack / adapt
collectionRepeat
или любого другого инструмента, подобного ему. Вот почему они называют это открытым исходным кодом. :-) (Тем не менее, команда Ionic делает довольно гениальные вещи, достойные вашего внимания.)Есть хотя бы один отличный пример того, как сделать что-то очень похожее в React. Только вместо того, чтобы повторно использовать элементы с обновленным содержимым, вы просто выбираете не отображать в дереве ничего, что не отображается. Он быстро работает на 5000 элементов, хотя их очень простая реализация POC позволяет немного мерцать ...
Также ... чтобы повторить некоторые другие сообщения, использование
track by
очень полезно, даже с небольшими наборами данных. Считайте это обязательным.источник
Я рекомендую увидеть это:
Оптимизация AngularJS: от 1200 до 35 мс
они создали новую директиву, оптимизировав ng-repeat в 4 частях:
проект находится здесь на github:
Использование:
1- включите эти файлы в ваше одностраничное приложение:
2 - добавить зависимость модуля:
3- заменить нг-повтор
Наслаждаться!
источник
sly-repeat
но ничего не помогло мне, результаты все еще медленны, а лаги браузера также получают нарушения[Violation] 'setTimeout' handler took 54ms
,[Violation] 'scroll' handler took 1298ms
Помимо всех вышеперечисленных советов, таких как отслеживание и меньшие циклы, этот также очень помог мне
этот фрагмент кода напечатает имя, как только оно будет загружено, и перестанет смотреть его после этого. Аналогично, для ng-повторов его можно использовать как
однако это работает только для AngularJS версии 1.3 и выше. С http://www.befundoo.com/blog/optimizing-ng-repeat-in-angularjs/
источник
::
на повтор, а также выражение? Документы говорят иначе, но я не уверен, как проверить, что это работает. docs.angularjs.org/guide/expressionВы можете использовать «отслеживать», чтобы увеличить производительность:
Быстрее, чем:
ссылка: https://www.airpair.com/angularjs/posts/angularjs-performance-large-applications
источник
Если все ваши строки имеют одинаковую высоту, вы обязательно должны взглянуть на виртуализирующий ng-repeat: http://kamilkp.github.io/angular-vs-repeat/
Это демо выглядит очень многообещающе (и поддерживает инерционную прокрутку)
источник
Правило № 1: никогда не позволяйте пользователю ждать чего-либо.
Это означает, что страница с растущей жизнью, которой требуется 10 секунд, выглядит намного быстрее, чем ждать 3 секунды перед пустым экраном и получать все сразу.
Поэтому вместо того, чтобы сделать страницу быстрой, просто позвольте странице выглядеть быстрой, даже если конечный результат будет медленнее:
Приведенный выше код позволяет отображать список построчно и всегда медленнее, чем рендеринг сразу. Но для пользователя это кажется быстрее.
источник
Виртуальная прокрутка - это еще один способ улучшить производительность прокрутки при работе с огромными списками и большим набором данных.
Один из способов реализовать это - использовать Angular Material,
md-virtual-repeat
как показано в этой демонстрации с 50 000 предметов.Взятые прямо из документации виртуального повтора:
источник
Другая версия @Steffomio
Вместо добавления каждого элемента по отдельности мы можем добавлять элементы по частям.
источник
Иногда, что происходило, вы получаете данные с сервера (или сервера) за несколько мс (например, я предполагаю, что это 100 мс), но для отображения на нашей веб-странице требуется больше времени (скажем, это занимает 900 мс для дисплей).
Итак, то, что здесь происходит, составляет 800 мс. Это просто для рендеринга веб-страницы.
В моем веб-приложении я использовал разбиение на страницы (или вы также можете использовать бесконечную прокрутку ) для отображения списка данных. Допустим, я показываю 50 данных / страницу.
Поэтому я не буду загружать все данные одновременно, только 50 данных, которые я загружаю изначально, что занимает всего 50 мс (я предполагаю здесь).
поэтому общее время здесь уменьшилось с 900 мс до 150 мс, как только пользователь запросит следующую страницу, затем отобразит следующие 50 данных и так далее.
Надеюсь, это поможет вам улучшить производительность. Всего наилучшего
источник
который загружает данные, когда он достигает нижней части страницы и удаляет половину ранее загруженных данных, и когда он снова достигает верхней части div, предыдущие данные (в зависимости от номера страницы) будут загружены, удаляя половину текущих данных. Итак, DOM в то же время присутствуют только ограниченные данные, что может привести к повышению производительности, а не к обработке целых данных под нагрузкой.
HTML-код:
Угловой код:
Демо с директивой
В зависимости от высоты деления он загружает данные, и при прокрутке новые данные добавляются, а предыдущие данные удаляются.
HTML-код:
Угловой код:
Демо с сеткой пользовательского интерфейса с бесконечной прокруткой Демо
источник
для большого набора данных и раскрывающегося множества значений лучше использовать
ng-options
, чемng-repeat
.ng-repeat
медленный, потому что он циклически перебирает все приходящие значения, ноng-options
просто отображается в опции выбора.намного намного быстрее чем
источник