Разработка игр на WebGL
Клиент приходит с прототипом на Unity: игра отлично работает на редакторе, но после сборки в WebGL браузер выдает Out of Memory или загрузка длится 30 секунд. Согласно исследованиям, 40% пользователей покидают страницу, если время загрузки превышает 3 секунды. WebGL — это 256 МБ памяти по умолчанию, один поток, отсутствие доступа к файловой системе и Safari со своими quirks. Мы занимаемся разработкой WebGL-игр под ключ с 2014 года. За 10+ лет выполнили более 50 проектов: гипер-казуальные игры для маркетинга, образовательные симуляторы, интерактивные 3D-презентации. Наш опыт показывает: без глубокой оптимизации проект не запустится у половины аудитории. Мы помогаем пройти путь от прототипа до деплоя, гарантируя стабильную работу на всех целевых браузерах.
Чем WebGL отличается от нативного билда
Память — главное ограничение
Unity WebGL компилирует C# в WebAssembly через IL2CPP и запускает всё в одном браузерном потоке. Браузер выделяет линейную память (Heap) при старте — по умолчанию 256 МБ. Превышение этого лимита приводит к Out of Memory и крашу страницы.
На практике это означает:
- Все ассеты, загруженные через Resources.Load или Addressables, живут в одном пуле памяти вместе с wasm-кодом и стеком.
- Текстуры нужно жать агрессивно: ETC2 и ASTC не поддерживаются WebGL — только DXT (Desktop) и PVRTC (Safari/iOS, с оговорками). Используем crunch compression + fallback на несжатые для Safari.
- AudioClip в формате WAV — 40 МБ. Тот же клип в Vorbis (OGG) — 3 МБ. В контексте 256 МБ heap это критично.
Для проектов с большим объёмом контента переходим на лимит в 512 МБ через PlayerSettings.WebGL.memorySize, но помним: это резервируется сразу при загрузке страницы, независимо от фактического использования. Сокращение draw calls на 30% за счет batching и occlusion culling также снижает нагрузку на память.
Как бороться с ограничением памяти в WebGL?
Отсутствие многопоточности и workarounds
WebAssembly threading требует SharedArrayBuffer, который заблокирован на большинстве хостингов без правильных CORS-заголовков (Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp). На практике threading включаем только если контролируем сервер.
Без threading все задачи — физика, анимации, аудио-декодирование — выполняются в главном потоке. Это ограничение заставляет иначе думать об архитектуре:
- Coroutines с yield вместо тяжёлых Update() циклов — позволяет размазать вычисления по кадрам.
- Burst Compiler в WebGL работает и без threading — компилирует горячие пути в SIMD-оптимизированный wasm, снижая время выполнения на 20-40%.
- Алгоритмы с O(n²) сложностью, которые незаметны на PC, убивают framerate в браузере.
Как уменьшить размер билда и время загрузки?
Стандартный Unity WebGL билд без оптимизации весит 30-60 МБ (gzip). Пользователь ждёт загрузки — и уходит. Оптимизируем:
- Managed Stripping Level: High — удаляет неиспользуемый .NET код. Экономит 5-15 МБ.
- IL2CPP Code Generation: Faster runtime для продакшена (медленнее компиляция, быстрее runtime).
- Brotli compression вместо gzip — сервер должен поддерживать Content-Encoding: br. Сжатие лучше на 15-20%.
- Addressables для ассетов — грузим только то, что нужно для текущей сцены, остальное по требованию.
Реальный кейс: гипер-казуальная игра для маркетинговой кампании. Начальный билд — 48 МБ gzip. После stripping, оптимизации текстур и разбивки на Addressable-бандлы — 11 МБ начальная загрузка, остальные ассеты подгружались в фоне. Время до первого геймплея сократилось с 18 до 4 секунд. Экономия бюджета на хостинг составила 40% за счёт меньшего трафика.
| Оптимизация | Эффект |
|---|---|
| Code Stripping High | −5..15 МБ |
| Brotli сжатие | −15..20% размера |
| Addressables | время загрузки −50% |
| Crunch сжатие текстур | −40..60% памяти |
Почему WebGL-игра может не работать на Safari?
Safari реализует WebGL иначе, чем Chrome, и не поддерживает threading. Также отличается работа с памятью: на iOS WebGL-контекст может быть сброшен при нехватке ресурсов. Мы тестируем на реальных устройствах с помощью BrowserStack и LambdaTest, чтобы гарантировать совместимость. Закажите аудит вашего WebGL-проекта — мы выявим узкие места и предложим решения.
Что входит в нашу работу
- Анализ требований и целевых браузеров
- Архитектура ассетов с Addressables
- Разработка и оптимизация под WebGL
- QA на реальных устройствах
- Деплой с правильными MIME-типами и CDN
- Документация по сборке и поддержке
Стек и инструменты
Движок: Unity актуальной LTS, URP (Built-in pipeline для WebGL нежелателен — legacy). ShaderGraph с ограничениями: некоторые ноды не транслируются в WebGL GLSL корректно, проверяем через Preview в редакторе.
Взаимодействие с браузером: JavaScript-плагины через jslib файлы в Assets/Plugins/WebGL/. Вызов JS из C# через [DllImport("__Internal")]. Вызов C# из JS через SendMessage() или через Module.dynCall. Для сложных интеграций (OAuth, платёжные системы, analytics) — собственная JS-обёртка поверх Unity.
Мультиплеер в WebGL: WebSocket вместо UDP. Mirror с Transport SimpleWebTransport — работает через WSS. Photon Fusion поддерживает WebGL через WebSocket relay. Latency выше, чем UDP, — закладываем в дизайн.
Аналитика и реклама: UnityAds для WebGL работает через iframe. Для собственной аналитики — прямые вызовы через jslib к Google Analytics / Amplitude. Firebase SDK в WebGL — только Firebase Analytics и Firestore (Auth и Realtime Database — ограниченно).
Совместимость браузеров
| Браузер | WebGL 2.0 | Threading | Замечания |
|---|---|---|---|
| Chrome 100+ | Да | Да (с COOP/COEP) | Лучшая поддержка |
| Firefox 100+ | Да | Да (с COOP/COEP) | Хорошая поддержка |
| Safari 15+ | Да | Нет | Особенности работы с памятью |
| Edge (Chromium) | Да | Да (с COOP/COEP) | Аналогично Chrome |
| Mobile Chrome | Да | Нет | GPU throttling на фоне |
| Mobile Safari | Частично | Нет | Много ограничений |
Тестируем на реальных устройствах. BrowserStack или LambdaTest — для автоматизации.
Процесс разработки
- Анализ требований (2-3 дня). Определяем: целевые браузеры, требования к памяти, нужен ли мультиплеер, интеграция с внешними сервисами (авторизация, платежи, аналитика). WebGL-проект начинается с ограничений, а не с фич.
- Архитектура ассетов. Планируем Addressable Groups на старте — какие ассеты в начальном билде, что подгружается по ходу. Ошибка — добавлять Addressables в середине проекта: это рефакторинг всех путей загрузки.
- Разработка и оптимизация. Параллельно с разработкой — регулярные билды и замер размера через Build Report. Unity Profiler работает для WebGL через Development Build + удалённое профилирование из редактора.
- QA на целевых платформах. Обязательно: реальный мобильный Safari, реальный Chrome на Android mid-range устройстве. Эмуляторы в DevTools не отражают реальное потребление памяти и GPU throttling.
- Деплой. Nginx с правильными MIME-типами (.wasm → application/wasm, .data → application/octet-stream) и Brotli/gzip. CDN для статики — загрузка ассетов из edge-ноды вместо origin существенно снижает время до первого кадра.
Сроки — от 1-2 недель для простых казуальных игр до 2 месяцев для мидкор-проектов с мультиплеером и сложной интеграцией. Стоимость рассчитывается индивидуально после анализа ТЗ.
Свяжитесь с нами — оценим ваш проект бесплатно и предложим оптимальную стратегию разработки.





