Carduelis
@Carduelis
Web-developer, front-end, js, less

Middle и senior js, поможешь как оптимизировать неоптимизируемое в js?

Привет, тебе опытный разработчик. Помоги справиться со следующей задачей.
Есть таблица с ячейками. Ячеек может быть 50000. Представим, что эти ячейки нужно заполнить инпутами: в зависимости от модели данных, это могут быть textarea, input или select.
Условие в том, что рендерить ячейки построчно нельзя. Можно только рендерить поле в ячейку.
Я использую шаблонизатор lodash и подтягиваю шаблон с инпутами, в зависимости от входной модели срабатывает тот или иной кусок шаблона и ренедерит select/input/textarea.
После целого дня дебаггинга я сделал следующие выводы:
  1. Если мы грузим все это синхронно то:
    • браузер висит,
    • пользователь думает, что все сломалось,
    • вентилятор компьютера думает, что мы играем в Crysis GTA V Far Cry 4.
    • Время рендера t.

  2. Если мы запускаем каждый рендер в setTimeout(render, 0), браузер отзывчив, поля появляются как бешеные, но появляются долго. Время рендера 3-4×t
  3. Время рендера одного поля от 5 до 7ms, время провиса между рекурсивными запусками setTimeout() — 25-35ms (!!!). Вот это неожиданно.
  4. Делаем рендер пачками. Для своего компа нашел опытным путем значение в 30 шт.. Время рендера уменьшилось, равняется 1,5-2×t


Вопросы:
  1. как уменьшить интервал между вызовами SetTimeout() ? с 30 ms до хотя бы 4ms
  2. Как уменьшить время рендера одного поля?
  3. Доля пользователей, имеющих 50000 полей мала. Они могут подождать, это интранет. 95% пользователей имеют 1000-2000 полей, и совершенно не хочется для основной массы ставить лоадер на 20-30 секунд, а свести его к минимуму, используя индикацию процесса рендера (которая тоже добавляет 10% к процессорному времени).
  4. Читал, что есть так-называемые web-workers, помогут ли они решить эту проблему? Как распараллелить вычисления?


P.S.: понятное дело, задачу можно решить иначе. Генерировать сервером, генерировать построчно таблицы. Но. Давайте посмотрим на это дело как на олимпиадную задачу, когда нельзя менять условия. Вот есть 50к полей, вот есть такая задача, Как выжать все соки?
  • Вопрос задан
  • 388 просмотров
Пригласить эксперта
Ответы на вопрос 2
Sanasol
@Sanasol Куратор тега JavaScript
нельзя просто так взять и загуглить ошибку
Никто не рендерит все ячейки сразу.

Рендерить достаточно только видимую область(а она уж точно не на 50к ячеек).
И тогда все будет летать на любых данных.

Так работают все коммерческие(и не только) более менее хорошие библиотеки.
Ответ написан
Taraflex
@Taraflex
Ищу работу. Контакты в профиле.
Ну я хоть не сеньёрь и даже не мидл, но подход у вас совершенно не правильный.
Как уже упомянул Александр Аксентьев рендерить нужно только видимые ячейки, но на 50000 только этого будет недостаточно.
Вам нужно организовать пулл dom элементов (генерим сразу максимальное число ячкеек которое влезает в экран и сразу вставляем их в dom). После только менять x,y позиции ячеек при прокрутке и сами текстовые данные внутри них.
То есть при прокручивании таблицы, вынимаем уже созданные ячейки из пула и расставляем их по необходимым координатам в строке, которая сейчас попадает в видимую область экрана.
Задача сильно упрощается, если размер ячеек фиксированный.
Я использую шаблонизатор lodash

На 50000 любая либа даст тормоза. Обрабатываем только ручками. В вашем случае не до удобства.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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