Hello everyone, for last few days i’ve been trying to gather resources for WebGL optimizations.
All the knowledge is spread through internet. I tested most of them and gathered all into a document.
These are what worked for my release build. These are essentials for WebGL but don’t forget this tips & tricks won’t magically boost any poorly optimized games performance
Also i forgot to save the forums & links i searched through while testing so i’m not able to share those threads
But i hope it helps;
Btw for some reason i’m not able to use This in code blocks i provided. So if you see a line starts and ends with “~~”, that line is the sample to avoid.
Project Settings
Graphics
- Remove all unused “Always Included Shaders”
Player ⇒ Other Settings
- Static Batching = true
- Graphic Jobs = true
- Texture Compression Format = ASTC (If you’re targeting Desktop devices you can use DXT)
- Lightmap Encoding = Low Quality
- HDR Cubemap Encoding = Low Quality
- Keep Loaded Shaders Alive = true
- Strip Engine Code = true
- Managed Stripping Level = Medium
Publishing Settings
- Enable Exceptions = Explicitly Thrown Exceptions Only
- Compression Format = Brotli (If not possible for your host , could be set to = Gzip.)
- Name Files As Hashes = true
- Data Caching = true
- Memory Growth Mode = Linear
- Maximum Memory Size = 2048
- Linear Memory Growth Step = 16
Quality
- VSync Count = Don’t Sync
- Realtime GI CPU Usage = Low
Build Settings
- Code Optimization = Disk Size with LTO
- This option increases build time significantly, so if it’s not a release build go with Shorter Build Time
- Max Texture Size = 512 (Depending on game but should be more than enough for most of the games)
URP Settings
- Settings Screenshot
Texture Import Settings
- Read/Write = false
- Generate Mipmaps = false
- Max size = 64 (Depends on Texture Quality needs but most Textures are OK with 64)
- Resize Algorithm = Mitchell
- Format = Automatic
- Compression = High Quality
- Use Crunch Compression = true
- Compressor Quality = 50 (Value can be adjusted by Quality needs)
Sound Import Settings
- Load Type = If it’s a background music or something similar = Compressed In Memory, else = Decompress On Load
- Compression Format = Vorbis
- Quality = 50 (Value can be adjusted by Quality needs)
- Sample Rate Setting = Preserve Sample Rate
Coding Tips & Tricks
This tricks are mostly targeting to reduce workload on GC
-
Avoid string manipulations
~~string sample = “Text1” + “Text2”;~~ System.Text.StringBuilder sb = new("Text"); sb.Append("Text2"); string sample = sb.ToString(); -
Cache Dynamic Functions
private void DoSomethingWithArrayOrList() { ~~Debug.Log(CountForSample()[0]); Debug.Log(CountForSample()[1]); Debug.Log(CountForSample()[2]);~~ List<int> countedList = CountForSample(); Debug.Log(countedList[0]); Debug.Log(countedList[1]); Debug.Log(countedList[2]); } private List<int> CountForSample() { List<int> countToTen = new(); for (int i = 0; i < 10; i++) countToTen.Add(i); return countToTen; } -
Avoid gameObject.tag - gameObject.CompareTag - gameObject.name usage
public class TagReplacer : MonoBehaviour { // If component is already on the object [SerializeField] private string StartTag; private void Awake() { if (!string.IsNullOrEmpty(StartTag)) { myTag = StartTag; } } // If component is added runtime public void Initialize(string tag) { myTag = tag; } private string myTag; // Use this instead of gameObject.CompareTag public bool CompareTagReplaced(string inputTag) { return myTag == inputTag; } } -
Cache Coroutines
WaitForSecondsRealtime WFSRT = new WaitForSecondsRealtime(1); IEnumerator Delay() { Debug.Log(3); ~~yield return new WaitForSecondsRealtime(1);~~ yield return WFSRT; Debug.Log(2); ~~yield return new WaitForSecondsRealtime(1);~~ yield return WFSRT; Debug.Log(1); ~~yield return new WaitForSecondsRealtime(1);~~ yield return WFSRT; Debug.Log(0); // Do stuff }
Other Tips & Tricks
- URP is generally performing better in WebGL builds
- AVOID GPU Instancing usage on your materials (Different browsers are causing different issues)
- Avoid Post Processing usage if possible
- Pool your objects
- Use simpler shaders
- If Skybox is not visible in game, don’t forget to set Camera ⇒ Environment ⇒ Background Type = Uninitialized
- Disable shadows or reduce their quality
Helpful Assets
-
You can track your asset usage and track build logs by this asset.
