@Levhav
Возьмусь за разработку проектов любой сложности.

Как работать с очень длинными списками в JavaScript (angular, react, vuejs)?

Как работать с очень длинными списками в JavaScript (angular, react, vuejs)?

У меня есть чат. В нём история сообщений. Если я работаю с jQuery то мне надо добавить сообщение к списку предыдущих командой
$("#chat-history").append("HTML код сообщения")

Если же это делать через нечто реактивное (angular, react, vuejs). Как на пример это делается в примерах todo list
На пример вот код из урока по vuejs
<ul class="todo-list">
      <li v-for="todo in filteredTodos"
        class="todo"
        :key="todo.id"
        :class="{ completed: todo.completed, editing: todo == editedTodo }">
        <div class="view">
          <input class="toggle" type="checkbox" v-model="todo.completed">
          <label @dblclick="editTodo(todo)">{{ todo.title }}</label>
          <button class="destroy" @click="removeTodo(todo)"></button>
        </div> 
      </li>
</ul>


Я добавлю в модель новое сообщение, а потом он в своих недрах насколько я понял перерисует целиком свой виртуальный dom и сравнит и вставит изменения в реальный dom. По моему опыту вёрстка одного сообщения может быть очень сложной если там есть смайлы или плеер для аудио сообщений или ещё что то подобное.

На какой длине списка сообщений такое начнёт работать заметно медленнее чем простой .append? Сколько примерно FPS можно иметь при сложной вёрстке сообщений и примерно 100 сообщений в истории + список контактов на примерно 50 контактов
  • Вопрос задан
  • 1753 просмотра
Решения вопроса 1
alvvi
@alvvi
export default apathy;
(angular не использует vdom, для него история другая)
перерисует целиком свой виртуальный dom

Давайте немного проясним: виртуальный DOM - это грубо говоря js объект содержащий другие объекты.
При добавлении нового сообщения туда добавится новый объект и весь DOM сравнится со старой версией с помощью diff-алгоритма специфичного для конкретного фреймворка.
И только результат этого сравнения добавится в реальный DOM.
Работа с объектом значительно быстрее работы с самим DOM-ом, поэтому чтобы оно начало работать заметно медленее у вас должен быть дикий уровень вложенности или очень большой DOM.

100 сообщений и 50 контактов - это небольшие цифры, с таким любой из упомянутых фреймворков справится без просадок.

Вот пример бенчмарков с большим количеством объектов(1000+) для многих фреймворков на примере незамысловатой таблицы:
www.stefankrause.net/js-frameworks-benchmark6/webd...
(там же есть ссылка на репо чтобы увидеть как она выглядит)
Как видите, там в таблицу уже содержащую 10 000 добавляется еще 1000(!) объектов, и многие фреймворки впонле с этим справляются.

В реальности же, вам вряд-ли придется добавлять такие цифры, потому что подгружают изначально обычно меньшее количество: такое, которое пользователь сможет увидеть в одном экране, все остальное догружается постепенно по мере надобности. То же самое касается вашей истории чата, ее стоит подгружать только за тот период, за который она необходима пользвателю.
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
kulakoff
@kulakoff Куратор тега Vue.js
Vue.js developing
Слишком абстрактные вопросы. Сделайте с вашей вёрсткой и оцените производительность. Целиком перерисовываться ничего не будет. У каждой подобной библиотеки свои механизмы улучшения производительности. В варианте с вью, у вас скорее всего произойдёт просто добавление в список одного элемента и сравнение других элементов на изменение. И далее перерисовка того, что изменилось.
Ответ написан
Комментировать
alexey-m-ukolov
@alexey-m-ukolov Куратор тега JavaScript
Разом все эти сообщения обычно и не рендерятся - отрисовывается то, что на экране и немного сверху и снизу. При скролле контейнеры переиспользуются и в DOM элементов не так много. Называется виртуальный список, для каждого указанного фреймворка есть реализации.
Ответ написан
Комментировать
@MaxBog
Алексей правильно говорит.
Из доки по Vue.js https://ru.vuejs.org/v2/guide/syntax.html
Для работы Vue компилирует шаблоны в render-функции виртуального DOM. В сочетании с системой реактивности Vue умеет определять минимальное количество компонентов для повторного рендеринга и применяет минимальное число манипуляций к DOM при изменении состояния приложения.
Ответ написан
Комментировать
profesor08
@profesor08 Куратор тега JavaScript
Проблем не будет. Для браузера эти количества ничего не значат. Заметно будет, когда там их тысячи будут. Но зачем рендерить тысячу сообщений, если можно только последний десяток актуальных, а если пользователь захочет, то подгрузить ему еще. Посмотри как это сделано в мессенджерах, у тебя изначально в чате доступно ограниченное количество сообщений, при прокрутке вверх, подгружаются более ранние. Тем самым тебе не надо хранить всю историю сообщений в памяти.
Ответ написан
Комментировать
В ангуляре для того, чтобы не перерисовывать весь список используется ngForTrackBy https://angular.io/api/common/NgForOf в реакте для этого используется проперти key, при чем он тебе не отрендерит шаблон, если ты его не укажешь
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы