id: 234 slug: web-server-setup-for-on-the-fly-asset-loading title_ua: "Налаштування веб-серверів для завантаження ассетів графіки на льоту" tags: [vr-ar]
Налаштування веб-серверів для завантаження ассетів графіки на льоту
Розмір APK VR-гри з повним контентом легко переваливає за 2 ГБ — це ліміт для Quest Store та близько до ліміту для Google Play. Стріміг ассетів вирішує цю проблему: у білд йдуть лише критичні для запуску ресурси, решта завантажується по вимозі. Але «завантажувати на льоту» та «завантажувати швидко та надійно» — різні задачі, друга цілком залежить від правильно налаштованого сервера.
Що потрібно від сервера, щоб AssetBundle стріміг працював нормально
AssetBundle — це не просто файл на HTTP. У нього є кілька властивостей, які впливають на вимоги до сервера.
Range запити обов'язкові. UnityWebRequest.GetAssetBundle() з кешуванням використовує HTTP Range header для перевірки: завантажений ли уже цей фрагмент, потрібно ли докачувати. Якщо сервер відповідає на Range: bytes=0-1023 повним файлом замість 206 Partial Content — кеш Unity не працює, кожен запуск перекачує весь bundle. Nginx за замовчуванням підтримує Range, але деякі CDN-конфігурації це відключають.
ETag / Last-Modified для cache validation. Unity AssetBundle Cache перевіряє версію через CacheControlParams або hash. Якщо сервер не відправляє ETag або Last-Modified, Unity не може визначити, чи змінився bundle — або скачує заново кожен раз, або працює з застарілою версією. Налаштування ETag у Nginx: etag on; — одна рядок, але часто забувають.
GZIP/Brotli лише для текстових ресурсів. AssetBundle у форматі LZ4 (оптимальний для real-time завантаження) не потрібно додатково стискати на рівні HTTP — лише зайві CPU-цикли на розпаковку. У Nginx: gzip_types повинен явно не включати application/octet-stream для бандлів.
CORS для WebGL. Якщо VR-контент працює через WebXR у браузері — сервер повинен відправляти правильні CORS-заголовки: Access-Control-Allow-Origin, Access-Control-Expose-Headers: Content-Length (потрібен для progress bar при завантаженні).
Архітектура сервера для ассет-стріміга
Типова схема: Origin сервер (зберігання masters, управління версіями) + CDN (дистрибуція, edge-кеш).
Для Origin використовуємо Nginx або Caddy. Caddy привабливіший для малих команд: автоматичний HTTPS через Let's Encrypt, конфігурація в одному Caddyfile, правильні заголовки за замовчуванням.
Структура URL ассетів включає версію: /assets/v{hash}/{bundleName}. При оновленні контенту змінюється hash у шляху — CDN не відправляє кеш, клієнт отримує новий bundle. Це надійніше cache-busting через query string (?v=123), який деякі CDN ігнорують.
Для CDN під VR-аудиторію (глобальна дистрибуція) добре працюють Cloudflare R2 + Cloudflare CDN (безплатний egress) або AWS S3 + CloudFront. Ключова налаштування CloudFront: Cache-Control: max-age=31536000, immutable для версіонованих бандлів, Cache-Control: no-cache для manifest-файлу (список актуальних bundle URL та хешів).
Asset Bundle Manifest — це окремий легкий файл (~10 КБ), який містить список усіх бандлів з хешами та залежностями. Клієнт завантажує його при запуску, порівнює з локальним кешем, скачує лише змінені бандли. Оновлення контенту без переустановки програми — через зміну записів у manifest та нові бандли на CDN.
Клієнтська сторона
У Unity — UnityWebRequestAssetBundle.GetAssetBundle(url, cachedVersion, crc). cachedVersion беремо з manifest. crc — додаткова перевірка цілісності (не обов'язкова, якщо TLS налаштований корректно).
Завантаження будуємо через чергу з пріоритетами: ассети поточної сцени — високий пріоритет, ассети наступної сцени — середній, decorative content — низький. Максимальна кількість паралельних запитів — 4–6 (обмеження HTTP/1.1, при HTTP/2 можна більше, але Unity WebRequest не завжди коректно мультиплексує).
Для Quest (Android) важливий ліміт Application.temporaryCachePath — не більше 1 ГБ рекомендується для кеша бандлів, інакше ОС починає агресивно чистити. Реалізуємо CacheEvictionPolicy з LRU: при досягненні ліміту видаляємо давно не використані бандли через Caching.ClearCachedVersion().
Етапи роботи
Аудит контенту. Які ассети йдуть у білд, які стримяться, стратегія версіонування.
Налаштування Origin + CDN. Nginx/Caddy конфігурація, S3/R2 bucket, правила кешування CDN.
Інструменти складання бандлів. AssetBundle Browser або Addressables з pipeline автоматичної складання при CI.
Клієнтський завантажувач. Queue, пріоритети, cache management, fallback при помилках мережі.
Навантажувальне тестування. 1000 одночасних клієнтів, деградація при 50% втраті пакетів.
| Масштаб | Орієнтовні строки |
|---|---|
| Простий CDN + AssetBundle завантажувач | 1–2 тижні |
| Повна система з версіонуванням та manifest | 3–5 тижнів |
| Глобальна CDN + аналітика завантажень + A/B контент | 2–3 місяці |
Вартість розраховується після аналізу обсягу контенту та вимог доступності.





