Site icon AppTractor

Как Spotify отслеживает размеры приложений

Введение

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

Неправильно, иногда новая отличная функция приносит больше вреда, чем пользы. Причина проста — размер приложения. Любое дополнение к приложению — будь то код для новой функции, ресурс изображения для новой кнопки или даже поддержка новой локализации — приводит к увеличению размера приложения. Вы можете спросить: «Неужели это действительно проблема в нашем современном мире?». Мы утверждаем, что да.

Так что же такое размер приложения?

Хотя ответ может показаться простым, на самом деле все не так однозначно. Мы можем говорить о размерах приложений по крайней мере в четырех вариантах:

  1. Размер загрузки:
    Размер приложения при его загрузке из магазина приложений пользователя, т.е. объем данных, передаваемых через Интернет. Чтобы передать как можно меньше данных через Интернет, размер загружаемого приложения сжимается.
  2. Размер при установке:
    Размер приложения непосредственно после установки на мобильное устройство, т.е. объем данных, хранящихся на диске после установки приложения. Для того чтобы приложение можно было использовать, установочный размер приложения — это содержимое приложения в несжатом виде.
  3. Размер хранилища:
    Размер приложения в использовании, т.е. установочный размер плюс место, занимаемое различными кэшами (аудиофайлы, изображения и т.д.), хранящимися на устройстве.
  4. Размер обновления:
    Размер приложения при загрузке обновления из App Store или Play Store. Этот размер может быть меньше размера загрузки, в зависимости от того, насколько сильно изменилось приложение.

Каждый из этих размеров приложений по-разному влияет на пользователей, но в целом их воздействие можно разделить на две области: связанную с сетью и связанную с хранилищем.

Почему размер приложения так важен?

В эпоху цифровых технологий все больше и больше людей могут пользоваться быстрой и доступной мобильной связью, повсеместным доступом к Wi-Fi в городах и безлимитным оптоволоконным подключением в домах, а также иметь до 1 ТБ дискового пространства на смартфонах и планшетах. Хотя для некоторых это действительно так, наши данные показывают, что значительное число людей на развивающихся рынках пользуются смартфонами старого поколения с меньшим объемом памяти — например, iPhone 6s с 16 ГБ дискового пространства, часть которого уже занята самой iOS. Соответственно, такие пользователи вынуждены выбирать, какой контент для них наиболее ценен и может быть сохранен на их устройствах. Учитывая, что на развивающихся рынках проживает 85% населения Земли, размер приложений становится все более важным для наших пользователей по всему миру. Хотя эти проблемы могут показаться теоретическими, мы располагаем данными, подтверждающими их реальность.

Компания Google провела эксперимент, предоставив пользователям идентичные сборки приложений, искусственно увеличенные в размерах. В результате эксперимента выяснилось, что на каждые 6 МБ увеличения размера приложения коэффициент его конверсии в установку снижался на 1%. Последствия этого весьма серьезны, они приводят к множеству упущенных возможностей.

Однако существует и менее очевидный, но не менее значимый аспект, связанный с размером приложений.

Мы часто слышим о глобальном потеплении и влиянии на него автомобилей, коров и электростанций, но влияние наших приложений — не только использование приложений, но и загрузка обновлений — обычно не ассоциируется с этой проблемой. Каждую неделю миллионы пользователей загружают новые версии своих приложений. Например, мы обнаружили, что приложения Spotify (iOS и Android) в 2022 году были обновлены более 20 млрд. раз. Если умножить это число на объем загружаемых приложений, то мы получим ошеломляющий объем сетевого трафика — 930+ петабайт. Мы можем сопоставить этот трафик с энергопотреблением при передаче данных. Используя модель одного байта, разработанную Shift Project, мы обнаружили, что передача одного байта по сети потребляет 1.52e-10 кВт-ч для Wi-Fi и 8.84e-10 кВт-ч для мобильных устройств. Таким образом, даже если принять оптимистичный сценарий 100% использования Wi-Fi, этот трафик означает минимальное энергопотребление в размере около 150 000 000 кВт-ч. Точного способа пересчета этих показателей в выбросы CO2 не существует, но мы можем взять данные EPA за 2019 год и вычислить, что это соответствует примерно 65 тыс. тонн CO2.

Чтобы представить эту цифру в перспективе, можно сказать, что 65 000 тонн CO2 примерно эквивалентны выбросам 65 000 человек, совершающих перелет в обе стороны по маршруту Лондон — Нью-Йорк. Таким образом, даже если мы уменьшим размер обоих приложений всего на 1 МБ, мы сократим ежегодный углеродный след на 560 тонн CO2 в год. Делая наши приложения меньше, мы не только помогаем нашим пользователям сэкономить место на своих устройствах, но и делаем нашу планету немного чище.

Сеть безопасности для размера приложений

Для защиты от неконтролируемого увеличения размера приложений мы включили защитные механизмы в различные этапы процесса разработки.

Процесс перед слиянияем

Каждый раз, когда кто-то инициирует pull request (PR) в наших клиентских репозиториях, срабатывает автоматическая проверка, оценивающая, как этот PR влияет на размер приложения. Эти проверки являются обязательной частью CI, и код не может быть объединен до тех пор, пока эти проверки не будут завершены.

Для выполнения этой проверки мы опираемся на две критические сборки: базовую, которая отражает текущее состояние основной ветки, и головную, которая является зеркальным отражением основной ветки, но включает изменения из PR, сделанные в ней. После того как эти две сборки готовы, мы отправляем их на обработку в Emerge Tools.

Emerge обрабатывает эти сборки и анализирует разницу в размере приложений между ними. После этого мы получаем полный отчет с результатами проверки.

Рисунок 1. Поток проверки размера приложений перед слиянием.

После того, как результаты проверки получены из Emerge, отчет становится доступен непосредственно в пул-реквесте.

Рисунок 2: Результаты проверки в GitHub.

Глядя на эти данные, как узнать, покрывают ли преимущества изменений, которые мы хотим объединить, затраты на соответствующее увеличение размера приложения или нет? Для этого мы установили порог в 50 КБ. Все, что меньше этого порога, может быть спокойно объединено без каких-либо дополнительных действий со стороны разработчика. Изменения кода, превышающие порог, блокируются, и требуется одобрение специальной команды, которая отслеживает и наблюдает за такими случаями. Эта команда учитывает множество факторов при определении того, можно ли объединять запрос, превышающий этот порог.

Процесс после слияния

Для повышения наблюдаемости и отслеживания влияния изменений мы создали специальный канал в Slack, на который поступает информация о каждом запросе на слияние, превысившем пороговое значение. Благодаря тому, что все эти значительные изменения в размере нашего приложения аккуратно собраны в одном месте, отслеживать и наблюдать за ними становится значительно проще.

Этот канал предназначен не только для выявления проблем, но и для празднования успехов и обмена положительными новостями. Тот же порог в 50 КБ применяется к PR, которые успешно уменьшают размер приложения. Если изменение кода положительно влияет на размер приложения и превышает пороговое значение (менее 50 КБ), в этом же канале появляется уведомление.

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

Атрибуция команд-владельцев

Наличие страховочной сети проверок — отличный способ предотвратить проникновение масштабных изменений в нашу кодовую базу. Но большинство пул-реквестов, как правило, меньше по размеру и не вызывают тревоги, поэтому при медленном росте, с изменениями «под радаром», все равно возникают проблемы. Со временем эти безобидные на первый взгляд дополнения к кодовой базе начинают накапливаться. Учитывая объем запросов на исправление, которые мы ежедневно мерджим, вполне естественно, что размер нашего приложения постепенно увеличивается. Это похоже на эффект снежного кома — каждый PR, каким бы маленьким он ни был, вносит свой маленький кусочек в пазл. И хотя сигналы тревоги молчат, размер приложения продолжает расти.

Чтобы решить эту проблему, мы оцениваем размер загрузки и установки каждого модуля компиляции и ресурсного файла в нашей кодовой базе, а также относим его к специальной команде, которой принадлежит этот модуль.

В отличие от PR-проверок, для этой работы нам нужна только одна сборка — в частности, самый последний снепшот мастер-ветки на момент выполнения. Мы загружаем эту сборку в Emerge для анализа, а в ответ, благодаря функции Compilation Unit Attribution, получаем подробную разбивку модулей компиляции и размер вклада каждого из них в размер загрузки и установки. Затем мы дополняем эти данные размерами ресурсов, собранными с помощью собственного набора скриптов.

Собрав все эти данные, мы обрабатываем их и группируем файлы по модулям. А поскольку у каждого модуля есть своя группа надзора, мы можем точно определить, кто за что отвечает.

Вся прелесть в том, что данные — это не просто сырые цифры. Они представлены в удобном интерфейсе, позволяющем каждой команде визуализировать и отслеживать свой вклад в размер приложения с течением времени.

Рисунок 3: Закулисная визуализация вклада команды в размер приложения.

Для большей наглядности мы также приводим статистику вклада каждой команды в размер приложения по сравнению с другими командами Spotify.

Рисунок 4: Сравнение вклада команды со средним показателем среди всех команд Spotify.

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

Работа в Spotify с размерами приложений на практике

Почему это сложнее, чем кажется

Легко сказать, что разработчики должны уделять приоритетное внимание оптимизации кода в связи с размером, но не всегда все так просто.

Одна из причин сложности в том, что оптимизация по размеру не является “бесплатным” действием. Всякий раз, когда вы рефакторите часть кода, чтобы в результате получить более компактный двоичный файл, вы, скорее всего, переносите проблему в другую область, которая чаще всего связана либо с производительностью — код в результате становится медленнее, либо с архитектурой — код теперь сложнее читается/управляется. Другими словами, оптимизация размера — это компромисс, и может так быть, что этот компромисс не стоит того.

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

Третья и последняя причина заключается в том, что иногда от этого просто невозможно убежать. Любой добавленный код приводит к увеличению размера двоичного файла, поэтому если вы работаете над большой и сложной функцией, то без увеличения размера установки приложения просто не обойтись. Чтобы учесть подобные случаи, мы создали так называемую политику размера приложений.

Политика размера приложения и процесс исключений из нее

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

В большинстве случаев для получения исключения требуется доказать, что предлагаемое изменение окажет положительное влияние на бизнес.

Заключение

Чтобы убедиться в том, что наши инструменты приносят пользу, мы разработали набор метрик и дашбордов, которые постоянно отслеживаем.

Однако эффект от проверок выходит за рамки PR, в которых появляются предупреждения, или графиков, на которых отображаются ценные данные о размерах приложений. Мы регулярно получаем вопросы, связанные с размерами приложений, в специальном канале Slack, и обнаружили, что инженеры Spotify любят уменьшать размеры своих PR, в результате чего, по приблизительным подсчетам, общий размер PR уменьшился на 20 МБ.

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

Источник

Exit mobile version