Привет, меня зовут Михаил Юдин, я Android-инженер в Авито. Хочу рассказать, в чём польза перформанса и как начать внедрять его в продукте. Осенью 2018 года у нас появилась команда перформанса — есть шаги и инструменты, которые нам помогли, поэтому пора делиться опытом.



Что такое перформанс


Мы поговорим про Perceived performance. На русском это что-то вроде воспринимаемой производительности — то, насколько быстрым ваш продукт кажется пользователю. Это важная часть пользовательского опыта. Возможно, даже более важная, чем реальная производительность.


Инструменты перформанса нужны, когда на сайте заметно, как подгружаются веб-шрифты или долго крутится колесико лоадера вместе картинки. Чтобы понять, долго — это сколько, есть общепринятые значения. Например, отклик за 100—300 миллисекунд мы воспринимаем как мгновенный. Это из-за свойств человеческого мозга — чтобы свести все сигналы внешнего мира в одну картинку, мозг сам задерживает отклик до 80 миллисекунд. Для нас эта разница незаметна.


Работа с перформансом помогает не терять пользователей. Например, человек заходит в приложение и какое-то время ждёт, пока запрос отправляется на бэкенд и возвращается обратно. Если в это время мы показываем ему пустой экран, пользователь взбесится и уйдет. Подумает, что приложение сломалось, или просто не захочет ждать. Но стоит добавить лоадер или вывести полезные сообщения — пользователь останется с нами.


Есть фрагменты приложения или сайта, которые нельзя сделать быстрее. Но вы можете создать у пользователя ощущение, что процесс занимает меньше времени, чем на самом деле. Лоадер или анимация перехода сами по себе не влияют на результат — это лишняя работа, которую совершает приложение. Но эти инструменты как бы дают пользователю обратную связь, сообщают, что всё работает и вот-вот загрузится.


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


Как это работает


Перформанс влияет на все продуктовые метрики и SEO-трафик. Медленные страницы раздражают пользователей и хуже ранжируются в поисковиках. Поэтому нужно сделать так, чтобы медленное казалось быстрее. Если запрос занимает много времени, есть способы создать впечатление быстрой загр��зки. Например, скелетон, лоадер, различная анимация экрана.


Эксперименты хорошо показывают, как перформанс влияет на продуктовые метрики. Мы замедлили в веб-версии Авито несколько экранов, поисковую выдачу, открытие карточек. Через две недели метрики показали, что целевые действия снизились. Замедление на две, четыре и шесть секунд привело к тому, что пользователи реже кликали на рекламу, смотрели меньше объявлений.



Надо учитывать контекст — это приложение для оказания первой медпомощи или онлайн-кинотеатр? Пользователь мёрзнет на остановке или лениво перебирает товары, лежа на диване? В разных ситуациях может быть разная готовность ждать. А ещё люди слишком разные, поэтому нет универсальной формулы, которая покажет вам идеальное время для задержки отклика.


Сервис может быть слишком быстрым. И это тоже надо учитывать, когда хочешь ускорить что-нибудь. Например, пять секунд подождать, пока рендерится сложная модель здания — это нормально. А за пять секунд получить заказ в ресторане — так себе ситуация. Такая скорость подозрительна: может, они готовят еду заранее или подают блюдо, от которого кто-то только что отказался? Нужно думать об ожиданиях пользователя.


Есть ситуации, когда не до перформанса. Например, у вас стартап, и главная задача — реализовать функциональность. Тогда работа с перформансом будет не в приоритете. Но если вы пишете приложение с единственной функцией, она должна работать идеально. Здесь такой инструмент может помочь.


Ускорение бэкенда


В Авито микросервисная архитектура. Это значит, что при каждом обращении на бэкенд, у нас разворачивается множество микросервисов. Поэтому мы применяли инструменты, которые лучше всего находят слабые места в такой структуре:


  • Opentracing (Jaeger). Это технология, которая позволяет отправлять request ID и составлять карту, на каком этапе что поломалось.
  • The Four Golden Signals: Latency, traffic, error, saturation. Это даже не инструмент, а глава из книги. Суть в том, что вы следите за ошибками, памятью, ресурсами. И когда вы делаете это, повышается качество перформанса.

Классические ошибки бэкенда, которые мы исправили через перформанс:


  • Выносить необязательные элементы в отдельный запрос. Обычно всё устроено так: пользователь отправляет с экрана запрос, а мы собираем всё на бэкенде и возвращаем ему. Из-за того, что все данные собираются и отправляются одним потоком, ответ приходит, допустим, через полторы секунды. Это долго, пользователь вне себя. Поэтому мы разделяем запрос. Например, подгружаем рекламу отдельно от остального контента.
  • Не запрашивать в цикле данные у базы. При внедрении цикла легко забыть про транзакцию. Если исправить такие ошибки, сэкономим ещё немного времени на отклик.
  • Распараллеливать запросы. Часто запросы идут не параллельно, а суммируются. Если их разделить, уменьшится общее время запроса. Здесь нужно учесть возможности языка. Например, в PHP такая опция зависит от версии.
  • Не запрашивать лишние данные. Это приходится проверять вручную. Но отказ от лишних запросов тоже даёт хорошее ускорение.
  • Переиспользовать данные. Если ваше приложение бесполезно офлайн, то не используйте базу. Например, в приложении Авито не получится запросить телефон продавца, если нет подключения. База в этом случае добавляет задержки. Поэтому мы решили складывать такие данные в отдельный фрагмент, который доступен только при активном приложении.
  • Time to content. Чтобы ускорить загрузку контента, можно проверить необходимость инициализации библиотек, классов в мейн-треде. А ещё просто убрать с мейн-треда или назначить ленивую загрузку для всего, что кажется лишним.
  • Дебаунсы. Это искусственно добавленная задержка отклика. Такое нужно, чтобы скрыть процессы загрузки, показав только результат. Если убрать дебаунсы, мы получим ускорение без лишних усилий.

Многое можно ускорить дёшево и без серьёзных вложений времени. Эти изменения лежат в условной «зеленой зоне» на кривой ускорения Шипилёва. Здесь сосредоточен самый большой объём возможных действий по ускорению. Всё, что в красной и жёлтой зонах требует значительных усилий и показывает не такой ощутимый результат.



Типичные ошибки фронтенда, которые мы исправили


Фронтенд сложнее для наблюдений, чем мобильное приложение. Обновления в приложении выкатывают раз в две недели, а на фронтенде что-то новое появляется несколько раз в день. Здесь больше пространства для изменений, которые могут снижать перформанс. Чтобы их вовремя замечать, мы пользовались этими инструментами:


  • Google Lighthouse. Это инструмент, который позволяет профилировать. Его можно встраивать в CI/CD.
  • Overlooker. Решение, аналогичное Lighthouse, но со своими преимуществами. Например, этот инструмент умеет предзаписывать сеть. Так вы получаете точные метрики, когда делаете перформанс-тесты на сайте. Еще Оверлукер показывает ретроспективные метрики.

Вот с какими ошибками помогают справиться эти инструменты:


  • Дублирование кода зависимостей. Из-за расхождения версий в разных внутренних пакетах могут дублироваться фрагменты кода.
  • Неиспользуемые CSS. Скрипты, которые блокируют загрузку страницы и утяжеляют рендер. Их удобно отслеживать и блокировать.
  • Тяжёлый рендер. Чтобы ускорить, нужно выделять асинхронные блоки. И быть осторожнее с тяжёлыми шрифтами.

Используйте перформанс-модель, чтобы увидеть слабые места продукта — и на фронтенде, и на бэкенде. Определите блоки, с которыми работаете и добавляйте Service Level Agreement. Например, мы видим, как загружается карточка объявления. На первом уровне — сама загрузка, подготовка и показ карточки. На втором — то же для похожих объявлений, рекомендаций. Третий уровень работает с рекламой. Мы замерили все уровни и добавили SLA. Затем задали для загрузки значения, ниже которых быть не должно. Теперь понятно, какие блоки можно ускорять и как их переставлять.


Как это внедрять


Мониторинг и перформанс-тесты. Настройте мониторинги метрик, а затем выстраивайте систему. А ещё полезно сесть командой и подумать, какую культуру перформанса вам хочется получить. Например, разработчик хочет проверить идею — внедрить какое-то изменение, провести тесты, сравнить метрики. Он может рассчитывать, что его поддержат остальные? Команда поделится опытом, даст всё необходимое для работы?


Мониторинги — это реактивный подход. Когда мы провели исследование, увидели проблему и отреагировали. А перформанс-тесты — проактивная стратегия. С ними мы проверяем, как решения влияют на перформанс. Если видим ухудшение, то не внедряем такое решение. Например, в Авито мы собираем две версии приложения — с изменениями, которые хотим внедрить, и действующую версию. На обеих прогоняем перформанс-тесты и сравниваем результаты.


Замедлите что-нибудь. Вы увидите нелинейную зависимость — медленные куски дают худшие метрики.


Посмотрите, что там у конкурентов. Нет смысла бросать все силы на секундное ускорение. Иногда нужно делать функциональность, а иногда — перформанс. Разберитесь, что для вас сейчас важно.


Проверьте самые медленные места — возможно, нужно почистить код, и этого будет достаточно. Например, мы обнаружили в коде остатки теста, который давно сняли. Каждый раз он давал замедление, хотя мы уже не снимаем эти данные. Убрали — получили ускорение.


«Рассинхронизируйте» загрузку данных. Правильно расставьте приоритеты. Если нужно показать 30 карточек товаров с названием и ценой, дайте вначале хотя бы текст.


Проводите тесты и мониторинги, смотрите на метрики. Если нужно, идите с этими цифрами к руководителю. Например, на карточке в приложении Авито есть лишняя секунда, а карточка отрисовывается 150 млн раз в день на четырёх платформах. За год получаем 1736 лет дополнительного ожидания. Если учесть, что средняя продолжительность жизни в России 73,7 года, то одна лишняя секунда на карточке превращается в 23,5 человеческих жизни за год. А Амазон подсчитал, что каждая лишняя секунда в год для них это 1,6 млрд долларов, которые можно было бы заработать. Эти подсчёты убеждают лучше, чем разговоры о гипотетической пользе перформанса для продукта.


Соберите единомышленников. Это бэкендеры, фронтендеры, мобильные разработчики. Хорошо, когда в команде перформанса есть product owner. Этот человек знает, что происходит в компании и чем занимаются другие команды. А еще он глобально смотрит на цели вашей команды, потому что хорошо знает продукт. Это помогает фокусироваться на главном.


Обучайте команду. Пусть разработчик пишет код сразу с учётом перформанс-стратегии. Это не столько про скорость, сколько про восприятие. Поэтому общайтесь еще и с дизайнерами.


Говорите с разработчиками и менеджерами про перформанс. Это важно, потому что так создается культура перформанса. Если внедрять перформанс сверху или начинать работу с ним без понимания пользы и целей — идея обречена на провал. Начните со сплит-тестов, покажите результаты. Проще заботиться о перформансе и продвигать его, когда у вас есть реальные цифры, понятные менеджеру.