Разработчик ускорил загрузку графиков Vigo Pulse вдвое
Разработчик переписал загрузку графиков в аналитическом продукте Vigo Pulse и перешёл на колоночный формат JSON с общим массивом времени. В демо на большом наборе данных такой ответ оказался в 3,3 раза меньше строчного после gzip, а время до готовых серий при скорости 4 Мбит/с сократилось примерно в 3,2 раза.
Раньше фронтенд отправлял запрос в промежуточный сервис на Node.js, тот через RabbitMQ обращался к Java-сервису, который брал данные из ClickHouse и сохранял их в S3. Ответ приходил в виде набора точек с повторяющимися временем, ключом сегмента и именами метрик, а браузер сам сортировал их по времени и готовил серии для Highcharts. Группировка точек по ключу уменьшила ответ примерно на 16% и время на 15%, но не снизила расход памяти в браузере.
Колоночный формат избавляет от повторения ключей и имён метрик, а значения уже разложены по общей временной сетке. На большом наборе он уменьшил ответ почти в 4 раза и примерно вдвое сократил время до готовых серий, а прирост памяти оказался ниже и на сервере, и в браузере. Отказ от передачи массива времени дал всего около 0,5% экономии на gzip-ответе, поэтому массив оставили.
При ограничении скорости до 4 Мбит/с переход к колонкам без сжатия сократил время до готовых серий с 37 до 10 секунд. Сжатие дало дополнительное ускорение: минимальную медиану для колоночного варианта показал Brotli — 1,78 секунды, что в 5,6 раза быстрее несжатых колонок и примерно в 21 раз быстрее исходного строчного ответа без сжатия.
Бинарный MessagePack в локальных тестах обрабатывался быстрее JSON, но его преимущество по размеру зависело от компрессора: с gzip он был примерно на 21% больше JSON, с Zstandard — примерно на 5% меньше. BSON оказался объёмнее и медленнее. В продукте оставили колоночный JSON, а сжатие уже настроено на reverse proxy.
В приложении также заменили Highcharts на ECharts с отрисовкой через Canvas. Если перед загрузкой ожидается больше 100 линий, пользователь видит предупреждение и может получить только таблицу с суммарными значениями, а при более чем 500 линиях остаются только суммарные данные. При фактическом количестве линий больше 32 отключаются анимации и подсветка при наведении, а толщина линий уменьшается с 2 до 1,5 пикселя.
В продукте на одном из больших запросов размер сжатого ответа уменьшился с 1 МБ до 500 КБ, а время до отрисовки графика при скорости 4 Мбит/с — с 3 до 1,5 секунды. Настройка фильтров теперь показывает доступную глубину истории и ожидаемую скорость запроса ещё до загрузки данных.