Вопрос по javascript, performance, dom – Производительность с бесконечной прокруткой или много элементов дом?

64

У меня есть вопрос о большом количестве эльменец и производительности.

Позволять'скажем, у меня есть 6000 элементов dom на странице, и количество элементов может быть увеличено, когда пользователь взаимодействует со страницей (пользователь прокручивает, чтобы создать новый элемент dom), например, twitter.

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

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

Есть ли другие способы улучшить страницу с большим количеством элементов DOM?

@slebetman // спасибо за понимание. Я проверю! Moon
Вы также должны знать, что ваш оконный менеджер уже удаляет невидимые пиксели с экрана, чтобы ускорить взаимодействие с пользовательским интерфейсом. Выполнение этого самостоятельно в javascript скорее всего замедлит, а не ускорит. slebetman
с вашим вторым комментарием, я думаю, установка показа, чтобы никто не выигралТ помочь. Moon
Если для параметра display установлено значение none, инициируется перекомпоновка, что полностью противоположно тому, что вы хотите, если вы хотите избежать перекомпоновки. Ничего не делатьT запускает оплавление. Установка видимости для скрытого также не вызовет перекомпоновку. Однако ничего делать не намного проще. slebetman

Ваш Ответ

2   ответа
24

http://engineering.linkedin.com/linkedin-ipad-5-techniques-smooth-infinite-scrolling-html5

Я посмотрел на Facebook, и они неПохоже, что-то делает с Firefox. При прокрутке вниз DOM-элементы в верхней части страницы нет изменить. Fire Fox'Использование памяти увеличивается до 500 мегабайт, прежде чем Facebook нене позволяет вам прокручивать дальше.

Твиттер выглядит так же, как Facebook.

Google Maps - это отдельная история - плитки карты вне поля зрения удаляются из DOM (хотя и не сразу).

// Спасибо, что нашли время, чтобы исследовать вашу находку. Я сделаю то же самое в ближайшее время. Moon
Было бы очень интересно посмотреть, как это сделает Pinterest. Похоже, они поняли это, поскольку они загружают элементы динамически, когда вы прокручиваете вниз и назад. Кажется, что они всегда имеют установленное количество пинов, загруженных на странице канала в любой момент времени. alex
94

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

Вот'То, что мы сделали, может или не может быть полезным для ваших целей:

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

Итак, первая часть заключается в расчете видимого порта просмотра. (Это зависит от того, как размещены ваши элементы, абсолютное / фиксированное / по умолчанию)
var top = document.scrollTop;
var width = window.innerWidth;
var height = window.innerHeight;

Еще несколько ресурсов, чтобы найти более кросс-браузерную область просмотра:

Получите размеры окна просмотра браузера с помощью JavaScript

Кросс-браузерный метод для определения scrollTop окна браузера

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

У нас уже было сбалансированное бинарное дерево поиска для редактирования текста, поэтому мы расширили его и для управления высотой строк, поэтому эта часть была для нас относительно простой. Я нене думаю, что тыВам понадобится сложная структура данных для управления высотой ваших элементов; простой массив или объект может подойти. Просто убедитесь, что вы можете легко запросить высоту и размеры. Теперь, как бы вы получили данные о высоте для всех ваших элементов. Очень простой (но вычислительно дорогой для большого количества элементов!)

var boundingRect = element.getBoundingClientRect()

я говорю с точки зрения чистого JavaScript, но если выВы используете JQuery,$.offset$.positionи перечисленные методыВот было бы весьма полезно.

Опять же, использование структуры данных важно только в качестве кэша, но если вы хотите, вы можете сделать это на лету (хотя, как яМы заявили, что эти операции дороги). Также остерегайтесь изменения стилей CSS и вызова этих методов. Эти функции вызывают перерисовку, поэтому выувидим проблему с производительностью.

Наконец, просто замените элементы за кадром, скажем, элемент с расчетной высотой

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

Создать

 с высотой css (в пикселях), равной сумме высот элементов

Пометьте его именем класса, чтобы вы знали, что это divУдалите все элементы из DOM, которые охватывает этот divвместо этого вставьте этот недавно созданный div

Повторите для элементов, которые лежатпосле видимый видовой экран.

Ищите прокрутки и изменения размера событий. При каждой прокрутке вам нужно будет возвращаться к своей структуре данных, удалять элементы-заполнители, создавать элементы, которые ранее были удалены с экрана, и, соответственно, добавлять новые элементы-заполнители.

:) Это'Это длинный и сложный метод, но для больших документов это значительно увеличило нашу производительность.

ТЛ; Dri»

Я не уверен, что я объяснил это правильно, но суть этого метода:

Знайте вертикальные размеры ваших элементовЗнать прокручиваемый порт просмотраПредставьте все элементы вне экрана одним div (высота равна сумме всех высот элементов, которые он покрывает)Всего вам понадобится два элемента div в любой момент времени, один для элементов над видимым окном просмотра, другой для элементов ниже.Следите за портом просмотра, прослушивая прокрутку и изменяя размеры событий. Воссоздать div и видимые элементы соответственно

Надеюсь это поможет.

@Moon: эта же техника, изложенная в этом ответе, была реализована в виде плагина.ClusterizeJS, Работает точно так, как ожидалось, и поддерживает четность элементов, если вам это нужно. И это действительно прекрасно работает! (К вашему сведению: яя не разработчик этого) Robert Koritnik
@GeneVayngrib всякий раз, когда вы удаляете элементы из dom и вставляете другие, браузер пропускает повторные элементы. Итак, я неЯ думаю, что вы можете избежать этого, используя этот метод. Тем не менее, вы можете уменьшить это, не просто показав один экран, а 3 экрана. Таким образом, для +/- 1 страница прокрутки там выигралбыть оплавлением. Mutahhir
// В этом есть смысл! Спасибо за ваше понимание! Moon
Кстати, ямы обнаружили, что это единственный способ обработать множество элементов DOM с разумным опытом прокрутки. Кроме того, выборка scrollTop в (jquery) обработчике прокрутки не делаетТ вызывает перерисовку. На самом деле это никогда не происходит, он только очищает очередь перерисовок и перерисовок, чтобы можно было вернуть последний актуальный scrollTop. Я предполагаю, что это уже актуально в тот момент, когда обрабатывается скроллвент. Joren Van Severen

Похожие вопросы