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

Как превратить цикл в асинхронный на js?

Доброго времени суток!
Дано: lodash, jQuery, ES6 без ограничений
Есть задача по рендеру html-блоков кода с переменными значениями на lodash в ячейки таблицы.
Отбросим вопрос, почему так пришлось и зачем это нужно, пусть у нас будет 100000 сферических в вакууме ячеек разных таблиц, с атрибутами: <td data-x="%x-id%" data-x="%y-id%"></td>

Есть шаблон для lodash, который содержит в себе 100 строк html. В зависимости от входных параметров результируется <input>, <textarea> или <select>, все они обрамлены небольшой bootstrap-лапшой и кучей атрибутов data-smth="smth_prop"

Работа алгоритма такая: на вход приходит внушительный массив информации о полях ввода, которые в цикле начинают рендериться с помощью lodash в html.

Как оказалось, если lodash берет шаблон из кеша браузера (каждый раз пытаясь загрузить его по ajax) рендер 400 полей происходит за 500ms-800ms -- результат приемлимый. Все к тому же происходит асинхронно, рендер происходит ровно после загрузки шаблона из кеша. Но подобная практика отвратительна -- мы посылаем столько запросов к серверу, сколько у нас полей. 10000 запросов. Да, они кешируются. Но это неправильно.

А вот если мы сохраним этот шаблон в localStorage, и lodash будет каждый раз брать его уже не из ajax-запроса, а из localStorage, то рендеринг тех же 400 полей произойдет за 2000ms! В 3-4 раза медленнее! Ну, а добавив к этому отсутствие асинхронности, получаем фриз браузера на 2 секунды.(представили 10000 ячеек? Получили минуту).

localStorage имеет ключ с названием url до шаблона, функция рендера перед загрузкой по ajax проверят наличие данных в localStorage по ключу, равному запрашиваемому url, например, ('template/input.tmpl'). Если там данные есть, не запускает ajax, а берет прямо оттуда. Если ключа нет - берет данные по ajax, как получил их, записывает в localStorage.

Заметил, что если уменьшить размер шаблона, то рендеринг происходит заметно быстрее. То есть, влияет на скорость количество текста для рендеринга. Если допустить, что localstorage не умеет кешироваться или просто медленный, и запрашивать его каждый раз неправильно, то я попробовал перед выполнением цикла рендера скопировать поэлементно его содержимое в просто-объект, и рендеру дать просто-объект -- результат тот же. Убираем вообще localstorage -- браузер посылает сотни ajax-запросов и быстрее парсит в разы =)
Что делать?
P.S.:
Скорость между $('[data-x="124"][data-y="345"]').append() и getElementById('x124_y345').innerHTML -- вообще не значительна
Скорость между
for (var i = orderedJSON.length - 1; i >= 0; i--) {}
и for (var i in orderedJSON) {} -- тем более
  • Вопрос задан
  • 232 просмотра
Пригласить эксперта
Ответы на вопрос 1
@sh84
А попробуйте все данные сериолизовать в 1 переменную, и сохранять в localStorage её - будет только 1 чтение и запись - должно быть быстрее.
Ответ написан
Ваш ответ на вопрос

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

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