Меня зовут Григорий Горбовской, я работаю в Web-команде департамента по экосистемным продуктам ВКонтакте, занимаюсь разработкой VKUI. 

Хочу вкратце рассказать, как мы написали 8 тестовых веб-приложений, подключили их к моно-репозиторию, автоматизировали аудит через Google Lighthouse с помощью GitHub Actions — и как решали проблемы, с которыми столкнулись.

VKUI — это полноценный UI-фреймворк, с помощью которого можно создавать интерфейсы, внешне неотличимые от тех, которые пользователь видит ВКонтакте. Он адаптивный, а это значит, что приложение на нём будет выглядеть хорошо как на смартфонах с iOS или Android, так и на больших экранах — планшетах и даже десктопе. Сегодня VKUI используется практически во всех сервисах платформы VK Mini Apps и важных разделах приложения ВКонтакте, которые надо быстро обновлять независимо от магазинов.

VKUI также активно применяется для экранов универсального приложения VK для iPhone и iPad. Это крупное обновление с поддержкой планшетов на iPadOS мы представили 1 апреля.

Адаптивный экран на VKUI
Адаптивный экран на VKUI

Масштабирование было внушительным — поэтому мы провели аудит, проанализировали проблемы, которые могут возникнуть у нас и пользователей при работе с VKUI, и заодно сравнили свои решения с продуктами ближайших конкурентов.

Какие задачи поставили

  1. Выявить главные проблемы производительности VKUI.

  2. Подготовить почву, чтобы развернуть автоматизированные бенчмарки библиотеки и наших веб-приложений на основеVKUI.

  3. Сравнить производительность VKUI и конкурирующих UI-фреймворков.

Технологический стек

Инструменты для организации процессов:

Чтобы проще взаимодействовать с несколькими веб-приложениями, в которых применяются разные UI-библиотеки, здесь используем lerna. Это удобный инструмент, с помощью которого мы объединили в большой проект ряд приложений с отличающимися зависимостями. 

Бенчмарки мы проводим через Google Lighthouse — официальный инструмент для измерения Web Vitals. Де-факто это стандарт индустрии для оценки производительности в вебе.

Самое важное делает GitHub Actions: связывает воедино сборку и аудит наших приложений.

Библиотеки, взятые для сравнения:

Название

Сайт или репозиторий

VKUI

github.com/VKCOM/VKUI

Material-UI

material-ui.com

Yandex UI

github.com/bem/yandex-ui

Fluent UI

github.com/microsoft/fluentui

Lightning

react.lightningdesignsystem.com

Adobe Spectrum

react-spectrum.adobe.com

Ant Design

ant.design

Framework7

framework7.io


Мы решили сравнить популярные UI-фреймворки, часть из которых основана на собственных дизайн-системах. В качестве базового шаблона на React использовали create-react-app, и на момент написания приложений брали самые актуальные версии библиотек.

Тестируемые приложения

Первым делом мы набросали 8 приложений. В каждом были такие страницы:

  1. Default — страница с адаптивной вёрсткой, содержит по 2–3 подстраницы.

    • На главной находится лента с однотипным контентом и предложением ввести код подтверждения (абстрактный). При его вводе на несколько секунд отображается полноэкранный спиннер загрузки.

    • Страница настроек, в которую входит модальное окно с примитивным редактированием профиля и очередным предложением ввести код.

    • Страница с простым диалогом — условно, с техподдержкой.

  2. List (Burn) — страница со списком из 500 элементов. Главный аспект, который нам хотелось проверить: как вложенность кликабельных элементов влияет на показатель Performance.

  3. 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

vkui-benchmark.surge.sh

Ant Design

ant-benchmark.surge.sh

Material UI

mui-benchmark.surge.sh

Framework7

f7-benchmark.surge.sh

Fluent UI

fluent-benchmark.surge.sh

Lightning

lightning-benchmark.surge.sh

Yandex UI

yandex-benchmark.surge.sh

Adobe Spectrum

spectrum-benchmark.surge.sh


Конфигурация сейчас выглядит так:

{
  "ci": {
    "collect": {
      "settings": {
        "preset": "desktop", // Desktop-пресет
        "maxWaitForFcp": 60000 // Время ожидания ответа от сервера
      }
    }
  }
}

После аудита всех приложений запускается задача finalize-report. Она форматирует полученные данные в удобную сравнительную таблицу (с помощью магии Markdown) и отправляет её комментарием к тикету. Удобненько, да?

Пример подобного репорта от 30 марта 2021 г.
Пример подобного репорта от 30 марта 2021 г.

Нестабильность результатов

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

Из отчётов Lighthouse выяснили следующее: по неведомым причинам сервер долго отвечал, и это привело к общему замедлению и снижению баллов. Изначально грешили на воркеры и хостинг в целом, и я решился задеплоить и провести бенчмарки на одном сервере. Результаты стали лучше, но такое странное поведение оставалось нелогичным.

Предупреждения из отчётов Google Lighthouse
Предупреждения из отчётов Google Lighthouse

GitHub Actions по умолчанию выполняет задачи параллельно, как и в нашем воркфлоу с бенчмарками. Решение — ограничить максимальное количество выполняющихся одновременно задач:

jobs.<job_id>.strategy.max-parallel: 1

Мы провели бенчмарк дважды, и — вуаля — результаты стали ощутимо стабильнее. Теперь можно переходить к результатам.

Результаты от 30 марта 2021 г.

VKUI (4.3.0) vs ant:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

ant

default

report

0.99

vkui (4.3.0)

modals

report

1

ant

modals

report

0.99

vkui (4.3.0)

list

report

0.94

ant

list

report

0.89

list - У ant нет схожего по сложности компонента для отрисовки сложных списков, но на 0,05 балла отстали.

VKUI (4.3.0) vs Framework7:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

f7

default

report

0.98

vkui (4.3.0)

modals

report

1

f7

modals

report

0.99

vkui (4.3.0)

list

report

0.94

f7

list

report

0.92

list - Framework7 не позволяет вложить одновременно checkbox и radio в компонент списка (List).

VKUI (4.3.0) vs Fluent:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

fluent

default

report

0.94

vkui (4.3.0)

modals

report

1

fluent

modals

report

0.99

vkui (4.3.0)

list

report

0.94

fluent

list

report

0.97

modals - Разница на уровне погрешности.

list - Fluent не имеет схожего по сложности компонента для отрисовки сложных списков.

VKUI (4.3.0) vs Lightning:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

lightning

default

report

0.95

vkui (4.3.0)

modals

report

1

lightning

modals

report

1

vkui (4.3.0)

list

report

0.94

lightning

list

report

0.99

list - Lightning не имеет схожего по сложности компонента для отрисовки сложных списков.

VKUI (4.3.0) vs mui:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

mui

default

report

0.93

vkui (4.3.0)

modals

report

1

mui

modals

report

0.96

vkui (4.3.0)

list

report

0.94

mui

list

report

0.77

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:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

spectrum

default

report

0.99

vkui (4.3.0)

modals

report

1

spectrum

modals

report

1

vkui (4.3.0)

list

report

0.94

spectrum

list

report

1

list - Spectrum не имеет схожего по сложности компонента для отрисовки сложных списков.

VKUI (4.3.0) vs yandex:

app

type (app link)

report

performance

vkui (4.3.0)

default

report

0.99

yandex

default

report

1

vkui (4.3.0)

modals

report

1

yandex

modals

report

1

vkui (4.3.0)

list

report

0.94

yandex

list

report

1

default - Разница на уровне погрешности.

list - Yandex-UI не имеет схожего по сложности компонента для отрисовки сложных списков.

modals - Модальные страницы в Yandex UI объективно легче.

Выводы из отчёта Lighthouse о VKUI

  • VKUI по показателям ± на одном уровне с другими библиотеками. Сильных просадок, как и значительного превосходства, нет.

  • Одно из явных проблемных мест — вложенные Tappable — протестированы на большом списке. Единственная библиотека, в которой полноценно реализован этот кейс, — Material-UI. И VKUI уверенно обходит её по производительности.

  • Lighthouse ругается на стили — после сборки много неиспользуемых. Они же замедляют First Contentful Paint. Над этим уже работают.

Два CSS-чанка, один из которых весит 27,6 кибибайт без сжатия в gz
Два CSS-чанка, один из которых весит 27,6 кибибайт без сжатия в gz

Планы на будущее vkui-benchmarks

Переход с хостинга статики на локальное тестирование должен сократить погрешность: уменьшится вероятность того, что из-за внешнего фактора станет ниже балл у того или иного веб-приложения. Ещё у нас в репортах есть показатель CPU/Memory Power — и он немного отличается в зависимости от воркеров, которые может дать GitHub. Из-за этого результаты в репортах могут разниться в пределах 0,01–0,03. Это можно решить введением перцентилей.

Также планируем сделать Lighthouse Server для сохранения статистики по бенчмаркам на каждый релиз.