Before optimising anything, build the size report and read it. Guessing at this wastes days on the wrong file, and the distribution is remarkably consistent across projects.
Textures, every time
Usually more than half. The usual causes:
- Import settings left at the default maximum for assets that render at a fraction of it
- Uncompressed or poorly compressed formats — platform-specific compression is not optional
- Atlases with large empty regions
- Sprites imported at source resolution because nobody changed it
Halving the max size on UI textures alone often takes a tenth off the build, and nobody can see the difference.
Audio, the easiest win nobody takes
Music imported uncompressed is the single most common large file in a casual game. Compress it, stream anything over a few seconds, and drop the sample rate — nobody is listening to your menu loop in studio quality on a phone speaker.
Unused assets that ship anyway
Anything in a Resources folder ships whether or not it is referenced. So does anything referenced by a scene in the build list, including scenes you forgot were in it. This is where the mysterious megabytes live.
The engine and its packages
Code stripping set to High removes what is genuinely unused, at the cost of breaking anything reached by reflection. It is worth the debugging. Open the package manifest and remove what the project no longer imports — the default template carries more than most games use.
Why it matters more on the web
On mobile a large build costs you installs. In the browser it costs you the player entirely — they are watching a loading bar with nothing invested, and they leave. See why WebGL builds fail on mobile for the rest of that story.
This is what we do day to day — Unity to WebGL porting at Factorial Studio.