Налаштування Server-Driven UI для мобільного додатку
Server-Driven UI — архітектурний паттерн, при якому сервер відправляє не лише дані, а й опис того, як їх відобразити. Мобільний клієнт — універсальний рендерер, який за JSON-схемою динамічно будує екрани. Airbnb використовує це у Ghost Platform, Airbnb Lottie та Epoxy. Mercado Libre застосовує до більшості екранів додатку.
Чому це складніше ніж здається
На перший погляд: «відправляємо JSON з описом екрана — клієнт рендерить». На практиці — це повнофункціональний runtime та UI-движок, який потрібно спроектувати, версіонувати, тестувати та підтримувати.
Версіонування схеми. Користувачі оновлюють додатки повільно. Якщо сервер відправляє "type": "new_component", а клієнт версії 2.1 його не знає — екран упадає або відобразиться неправильно. Потрібна стратегія: fallback компонент, мінімально підтримувана версія, graceful degradation.
Типізація та валідація. Без суворої схеми (JSON Schema, Protobuf, kotlinx.serialization з sealed classes) сервер може відправити невалідний payload, і крах буде на клієнті, а не там де помилка. На iOS — Codable з DecodingStrategy.useDefaultValues, на Android — @SerialName + sealed class з @JsonClassDiscriminator.
Продуктивність парсингу. Складний екран у JSON — 5–50 KB. На кожен скролл стрічки це не перераховується, але холодний рендер при першому відкритті + кеширування схеми — окрема інженерна задача.
Архітектура SDUI-системи
Серверна частина
Сервер зберігає дерево компонентів для кожного екрана. Структура:
{
"version": "1.0",
"screen": {
"type": "scroll_view",
"children": [
{
"type": "hero_banner",
"props": {
"imageUrl": "https://cdn.example.com/banner.jpg",
"title": "Літня розпродаж",
"action": { "type": "navigate", "route": "/sale" }
}
},
{
"type": "product_grid",
"props": {
"columns": 2,
"dataSource": { "endpoint": "/api/products/featured" }
}
}
]
}
}
Компонентна система — реєстр типів: hero_banner, product_grid, text_block, cta_button, carousel. Новий тип компонента додається на сервері та клієнті одночасно, розгортається через App Store/Play Store з новою версією додатку.
Клієнтська частина (iOS — SwiftUI)
// Component Registry — реєстр усіх відомих типів
enum ComponentType: String, Codable {
case heroBanner = "hero_banner"
case productGrid = "product_grid"
case unknown
}
// Renderer — рекурсивний рендер дерева
@ViewBuilder
func renderComponent(_ component: SDUIComponent) -> some View {
switch component.type {
case .heroBanner:
HeroBannerView(props: component.props)
case .productGrid:
ProductGridView(props: component.props)
default:
// Graceful fallback для невідомих типів
EmptyView()
}
}
На Android — аналогічно через Jetpack Compose з when (component.type). Flutter — switch за типом з фабричним методом для кожного widget.
Коли SDUI виправданий
- Частих змін лейауту без релізу додатку (маркетингові банери, промо-екрани, екрани онбордингу)
- A/B тести на рівні екранів: сервер відправляє різні схеми різним сегментам користувачів
- Кількох брендів в одному додатку: white-label, де кожен клієнт бачить свій екран
- Потужної редакційної команди: CMS-інтерфейс дозволяє нетехнічному персоналу змінювати екрани
Коли SDUI не потрібен: додаток зі стабільним UI, мала команда, немає бізнес-вимог менювати екрани без релізу App Store.
Реальний приклад
Ритейл-додаток, iOS + Android. Маркетингова команда хотіла щотижневих змін головного екрана (банери, категорії, рекомендації)—без чекання 2–3 тижнів на App Store Review. SDUI впроваджувався поетапно: спершу лише головний екран (Hero Banner + Category Grid), через три місяці — сторінки категорій та картки товарів. Backend — CMS на Laravel з візуальним редактором схеми. Клієнт — iOS SwiftUI, Android Compose. Через 4 місяці маркетинг самостійно публікує нові екрани без участі мобільних розробників.
Інфраструктура та CDN
Схеми екранів кешуються на CDN (CloudFront, Fastly) з Cache-Control: max-age=300. Інвалідація через stale-while-revalidate — користувач одразу бачить кешовану версію, в фоні завантажується свіжа. Для критичних змін — Surrogate-Key для точкової інвалідації конкретного екрана.
Час реалізації: базова SDUI-система (3–5 типів компонентів, один екран) — 4–6 тижнів. Повнофункціональна платформа з CMS-редактором, A/B тестингом, версіонуванням схем — 12–20 тижнів.







