> For the complete documentation index, see [llms.txt](https://wiki.playgama.com/playgama/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.playgama.com/playgama/guides/performance-and-optimization.md).

# Performance & Optimization

Size, load time, memory and frame-rate targets, asset formats, the frame loop and WebGL context loss.

Performance work starts with the first playable moment: the game should load quickly, stay responsive, and avoid unnecessary downloads before the player can interact. The limits moderation checks are section 1.3 of the [Technical Requirements](/playgama/game-requirements/technical-requirements.md) and the [Engine-Specific Requirements](/playgama/game-requirements/engine-specific-requirements.md); this guide is about staying well inside them.

## Targets

These are guidelines, not moderation limits — but games that miss them lose players and partner platforms:

| Metric                                                               | Target                                               | Why                                                                                         |
| -------------------------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| Initial download (everything loaded before the first playable frame) | under 5 MB; under 20 MB at most                      | every extra megabyte loses players on mobile networks; several partner platforms cap it     |
| Time to the first playable frame                                     | under 5 seconds; never over 10                       | players leave a loading screen within seconds                                               |
| Memory                                                               | under 300–500 MB on mobile                           | iOS reloads or closes a tab that uses too much memory, without any error the game can catch |
| Frame rate                                                           | a stable 60 FPS on mid-range devices, never below 30 | stutter in the first minute reads as a broken game                                          |

The automatic build check measures the start-up memory and refuses an archive that peaks above 2 GB (item 1.3.3).

## Initial download

* Split the game: the first scene, the interface and the sounds it needs go into the initial download; everything else is loaded after `game_ready` or when the player gets there.
* Load later levels, music, cutscenes and other languages on demand, in the background.
* Serve compressed builds (Brotli or gzip) and do not ship source maps, debug builds, unused fonts or editor-only assets.
* Count everything the page downloads before the first playable frame, not just the archive size: a 300 MB archive is allowed (item 1.3.1), a 300 MB initial download is not playable.

## Assets

* **Textures.** Pack sprites into atlases, cap textures at 2048 px on mobile, and use GPU-compressed formats (KTX2/Basis, ASTC, ETC2) in WebGL games. Use WebP or compressed PNG for 2D images.
* **Audio.** OGG or MP3, never WAV; stream long music instead of decoding it in full (see [Sound](/playgama/guides/game-development/sound.md)).
* **3D.** Budget draw calls, not polygons: the bottleneck is usually the number of meshes, and a scene with tens of thousands of triangles can run worse than one twice as heavy but merged into a few meshes. Merge static meshes and reuse materials. Asset packs painted from one shared palette texture batch into a single draw call, while a model with its own 2K texture costs one of its own.
* **Asset pipeline.** Script compression into one command instead of optimizing by hand: lossless glTF compression cuts size several times over, and the originals stay in a folder that never ships. Do not strip node names to save bytes if the game finds parts of a model by name.
* **Fonts.** Ship only the glyphs and weights the game uses; system fonts cost nothing.

## Runtime

* Drive the game with `requestAnimationFrame` and delta time: physics and animation must run at the same speed at 60 Hz, 120 Hz and 144 Hz.
* Cap the frame rate at 60 on high-refresh phones to avoid overheating and throttling.
* Stop the game loop, timers and audio while the game is paused by the platform or an ad ([`PAUSE_STATE_CHANGED`](/playgama/bridge-sdk/api/platform.md#pause)) and while the page is hidden.
* Release textures, audio buffers and scenes the player has left; watch the memory graph over a long session, not only at start.
* Avoid allocations in the frame loop — creating objects every frame causes garbage-collection pauses that show up as stutter.
* Handle WebGL context loss: listen for `webglcontextlost` (call `preventDefault()`) and `webglcontextrestored`, and re-upload resources — or at least show a "tap to reload" screen instead of a frozen canvas.

## Measure

* Profile on a real mid-range Android phone and an iPhone, not only on a desktop.
* Ignore the first 5–10 seconds when you judge the frame rate: shaders are compiling and the first meshes are being built. An automatic quality downgrade must not run inside that window.
* Work with numbers: while JS time per frame is above 10 ms, changing graphics settings will not help — find what the script is doing.
* Send an aggregated performance sample through [`analytics.send`](/playgama/bridge-sdk/api/analytics.md) — average and percentile frame times over about 30 seconds of active play — to see how the game runs on players' devices.

Engine-specific implementation details are listed in child pages.
