Команда Tinder прагне робити знайомства простими й приємними для нового покоління користувачів, але з часом код Android-застосунку розрісся й став надто складним для підтримки. До останніх оптимізаційних змін приблизно 70% коду залишалося неоптимізованим, а сам застосунок містив 17 dex-файлів, з яких три відповідали лише за запуск. R8 у Tinder вже вмикали раніше, проте значну частину його можливостей блокували правила збереження (keep rules), і команда не могла точно визначити, які саме з них заважають оптимізації. Аби прискорити запуск і зменшити кількість помилок ANR (Application Not Responding), які відчувають користувачі, у Tinder звернулися до нового інструмента R8 Configuration Analyzer.

Завдяки цьому аналізатору команда змогла знайти й прибрати випадкові перепони для оптимізації. Результат виявився суттєвим: холодні старти застосунку скоротилися на 47%, розмір застосунку для завантаження зменшився на 28,98% (до 61,5 МБ), а кількість ANR-помилок, що їх помічають користувачі, впала на 28%.

Що показує аналізатор конфігурації

R8 Configuration Analyzer відображає ефективність оптимізації через показники скорочення, оптимізації та обфускації коду, вказуючи ділянки, які можна покращити. Інструмент показує надто широкі, надлишкові чи застарілі keep-правила, зокрема ті, що надходять із зовнішніх бібліотек, тож розробники можуть оцінити їхній вплив і відповідно скоригувати.

Основні метрики, які показує аналізатор:

  • Shrinking Score — відсоток коду, доступний для скорочення R8.
  • Optimization Score — відсоток коду, відкритий для оптимізації (наприклад, інлайнінг методів, горизонтальне злиття класів).
  • Obfuscation Score — відсоток класів, методів і полів, які R8 може перейменувати для зменшення розміру.

Аналізатор також допомагає перевіряти keep-правила та їхній вплив:

  • Пошук занадто широких правил: звузити правила, що діють на цілі пакети й обмежують оптимізацію R8, та визначити конкретні класи, методи й поля, виключені зі скорочення, оптимізації й обфускації.
  • Уточнення правил: залишити правила лише для тих класів/методів, яким справді потрібна рефлексія, і відкрити оптимізацію для решти.
  • Видалення зайвих правил: прибрати правила, що не стосуються жодного класу, методу чи поля в поточній збірці.
  • Виявлення однакових правил: коли кілька keep-правил стосуються тих самих класів, полів і методів або дублюються в одному чи різних файлах правил.
  • Пошук поглинутих правил: почистити вузькі правила, які вже покриваються ширшими конфігураціями.
  • Виявлення проблемних бібліотек: перевірити сукупний вплив на оптимізацію від об’єднаних keep-правил усіх підключених бібліотек.

Для роботи з R8 Configuration Analyzer через агентні інструменти було випущено окремий R8 Analyzer skill. Він спрощує автоматизовані процеси розробки, підсумовуючи звіт аналізатора та показуючи ключові показники оптимізації, обфускації й скорочення. Крім того, він виділяє п’ять найвпливовіших keep-правил, даючи чітке розуміння того, що саме блокує оптимізацію коду.

Як знайшли приховані перепони оптимізації

До впровадження R8 Configuration Analyzer Android-застосунок Tinder накопичив значний технічний борг через сильно неоптимізований код. Це напряму погіршувало досвід користувачів, спричиняючи повільні холодні старти.

Щоб розібратися із ситуацією, команда Tinder провела повний аудит конфігурації R8 за допомогою аналізатора. З'ясувалося, що оптимізація коду становила лише близько 28%, навіть попри увімкнений повний режим R8. Аналіз показав: одна з внутрішніх бібліотек компанії додавала занадто широке, невизначене за обсягом keep-правило.

# Prevents optimization in all public classes along with all of their public and protected members -keep public class * { public protected *; }

Це «широке» правило випадково охоплювало безліч залежностей у всьому застосунку, унеможливлюючи оптимізацію величезної кількості класів. Оскільки надто широке правило запобігало збоям під час виконання, розробники часто забували додавати нові правила для нових функцій, які використовували рефлексію, — і приховані проблеми накопичувалися роками.

Використовуючи дані з R8 Configuration Analyzer, команда відстежила й проаналізувала конкретні класи, на які впливало це широке правило з бібліотеки. Одразу з'ясувалося, що оптимізацію блокували великі класи, які не викликалися динамічно і які R8 цілком міг би оптимізувати. Уточнення цього одного правила дало Tinder змогу розкрити значний потенціал оптимізації, розплутати застарілі конфігурації й різко покращити загальні показники: значення R8 зросло з 28% до 50%, що одразу відбилося на продуктивності всього застосунку. Команда Tinder продовжує працювати над подальшим покращенням цього показника.

  • Швидше завантаження: кількість користувачів, які стикалися з повільним холодним стартом застосунку, скоротилася на 47%.
  • Менший розмір: розмір застосунку для завантаження зменшився з 86,6 МБ до 61,5 МБ (на 28,98%).
  • Вища стабільність: частка ANR-помилок, які помічають користувачі, знизилася з 0,35% до 0,28%, наблизившись до медіанних показників серед подібних застосунків.
  • Менша складність: загальна кількість DEX-файлів скоротилася з 17 до 11, з них лише два відповідають за запуск.

Крім суто технічних покращень, збільшена оптимізація застосунку прямо позначилася на бізнес-показниках і залученості користувачів, особливо на ринках із обмеженими ресурсами пристроїв.

  • Регіональна залученість: у країнах, де значну частку ринку становлять пристрої з малим обсягом оперативної пам’яті, спостерігалося найбільше зростання залученості, а зниження частоти ANR стало ключовим фактором покращення на цих великих ринках.
  • Зростання залученості: з моменту підвищення оптимізації застосунку залученість зросла на 3%.

Захист продуктивності через безперервну інтеграцію

Робота з мініфікацією коду — не одноразова акція, а процес, який потребує постійного контролю. Надихнувшись значними результатами, отриманими завдяки R8 Configuration Analyzer, команда Android-розробників Tinder додала моніторинг оптимізації до щоденного робочого процесу, щоб запобігти регресу.

У конвеєр CI/CD додали окреме завдання, яке звітує про зміни в показниках оптимізації, щоб кожен розробник бачив, як його зміни впливають на результат. Радячи іншим командам, які розглядають впровадження конфігурації R8, у Tinder наголошують на важливості аудиту внутрішніх залежностей. Хоча більшість популярних сторонніх бібліотек мають чітко визначені правила, внутрішні проєкти компанії, які вважаються «стабільними», насправді можуть містити занадто широкі правила, що негативно впливають на загальну оптимізацію.

Головні висновки

Маючи справу з сильно неоптимізованим кодом і великою кількістю DEX-файлів, Tinder потребував способу чітко перевірити правила мініфікації застосунку. R8 Configuration Analyzer надав необхідний інструментарій для виявлення надто широких внутрішніх бібліотечних правил і класів, на які вони впливали, що дозволило команді впевнено оптимізувати кодову базу. У підсумку Tinder скоротив холодні старти майже вдвічі, зменшив розмір APK більш ніж на 28% і заклав здоровішу, продуктивнішу основу для своїх користувачів, а команда продовжує працювати над подальшим покращенням цих показників.

Як користуватися R8 Configuration Analyzer

R8 Configuration Analyzer та його окремі функції можна використовувати залежно від поточної версії Android Gradle Plugin (AGP):

  • Реліз AGP 9.3: R8 Configuration Analyzer повністю інтегрований та випущений разом з AGP 9.3. Під час запуску релізної збірки з R8 звіт формується у папці build/outputs/mapping/release/configanalyzer.html.
  • Окреме завдання Gradle: AGP 9.3 додає окреме завдання Gradle, яке дає змогу згенерувати звіт аналізатора без запуску повної релізної збірки, забезпечуючи набагато швидший цикл зворотного зв'язку під час локального налаштування keep-правил: ./gradlew :app:analyzeReleaseR8Config. Звіт з'являється у build/reports/r8/r8-config-analyzer-release.html.
  • Використання на старіших версіях AGP: якщо у вас версія нижча за AGP 9.3, повністю мігрувати AGP не потрібно, щоб проаналізувати конфігурацію. Версію R8 можна оновити окремо до 9.3.7-dev або новішої, дотримуючись інструкцій із заміни R8 в AGP. Щоб згенерувати звіт локально, запустіть збірку із зазначеною властивістю: ./gradlew assembleRelease -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=.

Детальніше можна дізнатися в документації до R8 Configuration Analyzer.

Джерело: Android Developers Blog