Меня зовут Григорий Горбовской, я работаю в Web-команде департамента по экосистемным продуктам ВКонтакте, занимаюсь разработкой VKUI.
Хочу вкратце рассказать, как мы написали 8 тестовых веб-приложений, подключили их к моно-репозиторию, автоматизировали аудит через Google Lighthouse с помощью GitHub Actions — и как решали проблемы, с которыми столкнулись.
VKUI — это полноценный UI-фреймворк, с помощью которого можно создавать интерфейсы, внешне неотличимые от тех, которые пользователь видит ВКонтакте. Он адаптивный, а это значит, что приложение на нём будет выглядеть хорошо как на смартфонах с iOS или Android, так и на больших экранах — планшетах и даже десктопе. Сегодня VKUI используется практически во всех сервисах платформы VK Mini Apps и важных разделах приложения ВКонтакте, которые надо быстро обновлять независимо от магазинов.
VKUI также активно применяется для экранов универсального приложения VK для iPhone и iPad. Это крупное обновление с поддержкой планшетов на iPadOS мы представили 1 апреля.
Масштабирование было внушительным — поэтому мы провели аудит, проанализировали проблемы, которые могут возникнуть у нас и пользователей при работе с VKUI, и заодно сравнили свои решения с продуктами ближайших конкурентов.
Какие задачи поставили
Выявить главные проблемы производительности VKUI.
Подготовить почву, чтобы развернуть автоматизированные бенчмарки библиотеки и наших веб-приложений на основеVKUI.
Сравнить производительность VKUI и конкурирующих UI-фреймворков.
Технологический стек
Инструменты для организации процессов:
Чтобы проще взаимодействовать с несколькими веб-приложениями, в которых применяются разные UI-библиотеки, здесь используем lerna. Это удобный инструмент, с помощью которого мы объединили в большой проект ряд приложений с отличающимися зависимостями.
Бенчмарки мы проводим через Google Lighthouse — официальный инструмент для измерения Web Vitals. Де-факто это стандарт индустрии для оценки производительности в вебе.
Самое важное делает GitHub Actions: связывает воедино сборку и аудит наших приложений.
Библиотеки, взятые для сравнения:
Название | Сайт или репозиторий |
VKUI | |
Material-UI | |
Yandex UI | |
Fluent UI | |
Lightning | |
Adobe Spectrum | |
Ant Design | |
Framework7 |
Мы решили сравнить популярные UI-фреймворки, часть из которых основана на собственных дизайн-системах. В качестве базового шаблона на React использовали create-react-app, и на момент написания приложений брали самые актуальные версии библиотек.
Тестируемые приложения
Первым делом мы набросали 8 приложений. В каждом были такие страницы:
Default — страница с адаптивной вёрсткой, содержит по 2–3 подстраницы.
На главной находится лента с однотипным контентом и предложением ввести код подтверждения (абстрактный). При его вводе на несколько секунд отображается полноэкранный спиннер загрузки.
Страница настроек, в которую входит модальное окно с примитивным редактированием профиля и очередным предложением ввести код.
Страница с простым диалогом — условно, с техподдержкой.
List (Burn) — страница со списком из 500 элементов. Главный аспект, который нам хотелось проверить: как вложенность кликабельных элементов влияет на показатель Performance.
Modals — страница с несколькими модальными окнами.
Не у всех UI-фреймворков есть аналогичные компоненты — недостающие мы заменяли на равнозначные им по функциональности. Ближе всего к VKUI по компонентам и видам их отображения оказались Material-UI и Framework7.
Сделать 8 таких приложений поначалу кажется простой задачей, но спустя неделю просто упарываешься писать одно и то же, но с разными библиотеками. У каждого UI-фреймворка своя документация, API и особенности. С некоторыми я сталкивался впервые. Особенно запомнился Yandex UI — кажется, совсем не предназначенный для использования сторонними разработчиками. Какие-то компоненты и описания параметров к ним удавалось найти, только копаясь в исходном коде. Ещё умилительно было обнаружить в компоненте хедера логотип Яндекса <3
Вернёмся к нашим приложениям. Когда были написаны первые три, мы начали параллельную работу над автоматизацией аудита:
Автоматизация
Подготовили два воркфлоу:
Build and Deploy — здесь в первую очередь автоматизировали процессы сборки и разворачивания. Используем surge, чтобы быстро публиковать статичные приложения. Но постепенно перейдём к их запуску и аудиту внутри GitHub Actions воркеров.
Run Benchmarks — а здесь создаётся issue-тикет в репозитории со ссылкой на активный воркфлоу, затем запускается Lighthouse CI Action по подготовленным ссылкам.
UI-фреймворк | URL на тестовое приложение |
VKUI | |
Ant Design | |
Material UI | |
Framework7 | |
Fluent UI | |
Lightning | |
Yandex UI | |
Adobe Spectrum |
Конфигурация сейчас выглядит так:
{
"ci": {
"collect": {
"settings": {
"preset": "desktop", // Desktop-пресет
"maxWaitForFcp": 60000 // Время ожидания ответа от сервера
}
}
}
}
После аудита всех приложений запускается задача finalize-report. Она форматирует полученные данные в удобную сравнительную таблицу (с помощью магии Markdown) и отправляет её комментарием к тикету. Удобненько, да?
Нестабильность результатов
На начальных стадиях мы столкнулись с нестабильностью результатов: в разных отчётах наблюдали сильную просадку баллов, причём всегда у разных приложений.
Из отчётов Lighthouse выяснили следующее: по неведомым причинам сервер долго отвечал, и это привело к общему замедлению и снижению баллов. Изначально грешили на воркеры и хостинг в целом, и я решился задеплоить и провести бенчмарки на одном сервере. Результаты стали лучше, но такое странное поведение оставалось нелогичным.
GitHub Actions по умолчанию выполняет задачи параллельно, как и в нашем воркфлоу с бенчмарками. Решение — ограничить максимальное количество выполняющихся одновременно задач:
jobs.<job_id>.strategy.max-parallel: 1
Мы провели бенчмарк дважды, и — вуаля — результаты стали ощутимо стабильнее. Теперь можно переходить к результатам.
Результаты от 30 марта 2021 г.
VKUI (4.3.0) vs ant:
list - У ant нет схожего по сложности компонента для отрисовки сложных списков, но на 0,05 балла отстали.
VKUI (4.3.0) vs Framework7:
list - Framework7 не позволяет вложить одновременно checkbox и radio в компонент списка (List).
VKUI (4.3.0) vs Fluent:
modals - Разница на уровне погрешности.
list - Fluent не имеет схожего по сложности компонента для отрисовки сложных списков.
VKUI (4.3.0) vs Lightning:
list - Lightning не имеет схожего по сложности компонента для отрисовки сложных списков.
VKUI (4.3.0) vs mui:
default и modals - Расхождение незначительное, у Material-UI проседает First Contentful Paint.
list - При примерно одинаковой загруженности списков в Material-UI и VKUI выигрываем по Average Render Time почти в три раза (~1328,6 мс в Material-UI vs ~476,4 мс в VKUI).
VKUI (4.3.0) vs spectrum:
list - Spectrum не имеет схожего по сложности компонента для отрисовки сложных списков.
VKUI (4.3.0) vs yandex:
default - Разница на уровне погрешности.
list - Yandex-UI не имеет схожего по сложности компонента для отрисовки сложных списков.
modals - Модальные страницы в Yandex UI объективно легче.
Выводы из отчёта Lighthouse о VKUI
VKUI по показателям ± на одном уровне с другими библиотеками. Сильных просадок, как и значительного превосходства, нет.
Одно из явных проблемных мест — вложенные Tappable — протестированы на большом списке. Единственная библиотека, в которой полноценно реализован этот кейс, — Material-UI. И VKUI уверенно обходит её по производительности.
Lighthouse ругается на стили — после сборки много неиспользуемых. Они же замедляют First Contentful Paint. Над этим уже работают.
Планы на будущее vkui-benchmarks
Переход с хостинга статики на локальное тестирование должен сократить погрешность: уменьшится вероятность того, что из-за внешнего фактора станет ниже балл у того или иного веб-приложения. Ещё у нас в репортах есть показатель CPU/Memory Power — и он немного отличается в зависимости от воркеров, которые может дать GitHub. Из-за этого результаты в репортах могут разниться в пределах 0,01–0,03. Это можно решить введением перцентилей.
Также планируем сделать Lighthouse Server для сохранения статистики по бенчмаркам на каждый релиз.
nin-jin
Что ж вы с калеками-то сравниваете? Взяли бы что-нибудь более взрослое: