unity webgl games build full checklist for unity 2022

Do a good optimization set up for unity webGL games can gain smaller package size and good performance. Here is a table that I work out for several project on building webGL H5 game and chrome extensions from unity project. Both of them are almost the same settings, but some of them are very different.

FieldH5 Web PageChrome Extension
Development Build
Code OptimizationDark Size with LTODark Size with LTO
Color SpaceGammaGamma
Auto Graphics API
Static Batching
Dynamic Batching
Graphics Jobs
IL2CPP Code GenerationFaster (smaller) buildsFaster (smaller) builds
C++ Compiler ConfigurationMasterMaster
Strip Engine Code
Managed Stripping LevelHighHigh
Optimize Mesh Data
Texture MipMap Stripping
Enable ExceptionsExplicitly Thrown Exceptions OnlyExplicitly Thrown Exceptions Only
Compression FormatBrotliDisabled
Name Files As Hashes
Data Caching
Debug SymbolsOffOff
Decompression Fallback
OthersDefaultDefault

The main goal here is to build a production version. That means the package and code will be highly optimized. If you want do debug it, you need to switch off some of those settings.

Code Optimization

Both Disk Size with LTO and Runtime Speed with LTO will have almost the same effect. But the office document says Dark Size with LTO will have smaller package size. If you work with small unity project, the size that was reduced by this set up is not obvious. And as a setup rule, I stick with Dark Size with LTO here.

Color Space – Gamma

WebGL: INVALID_ENUM: getInternalformatParameter: invalid internalformat

There is a warning in console while playing untidy webGL game. I dig it a bit. When the internalformat value is one of the array [36759, 36760, 36761, 36763, 36756, 36757], the warning happen. The GPTs told me that it check something like GL_STENCIAL buffer that was not supported in webGL. Set up Color Space to Gamma can improve this warning. Of course there are other solution should be applied to fully fix it.

  • Use deferred rendering
  • No depth texture for camera, especially for post process effect
  • HDR and MSAA set to Off on Camera component
  • Disable soft shadow
  • And more …

Compression Format / Decompression Fallback

Two compression format: Brotli and Gzip. Brotli can compress data more and package will be smaller than the ones which compressed with Gzip.

If you use compressed data, you need to tell browser which compress method you are using in Content-encoding field.

If you build for chrome extension, there is no way to tell chrome the Content-encoding value, we will set Compression format to Disabled usually.

If you host your build data which CDN server not support Content-encoding field, you just need to check Decompression Fallback. The browser will work, but a warning will display in console.

Based on the Compression Format and Decompression Fallback settings combines, the file extension will be different as following table display.

Compression FormatDecompression Fallback ✅Decompression Fallback ❌
Dsiabled.wasm .wasm
Brotli.wasm.unityweb.wasm.br
gzip.wasm.unityweb.wasm.gz

Data Caching

As the title explain, it will cache data and reduce the download internet bands. But it will validate the download data. The user can access the webGL game faster next time. This is a recommend option for most game developer.

If it built for chrome extension, Data Caching should switch off. Otherwise it will not work.

By the way, the way I built unity webGL game as chrome extension is just launch the game index.html in a chrome tab. This is very straightforward and easy to do.

// background.js
chrome.action.onClicked.addListener((tab) => {
    chrome.tabs.create({
        url: chrome.runtime.getURL('index.html')
      });
  })

And set the game in a sandbox in the manifest.json

  // manifest.json
  "permissions": [
    "tabs"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self';"
  },
  "sandbox": {
    "pages": [ "index.html" ]
  },
  "icons": {
    "128": "icon128.png"
  }

Strip Engine Code / Managed Stripping Level

Most of time, we will switch on Strip Engine Code, and set Managed Stripping Level to High. This will reduce the code size a lots.

In some cause, you need to take it very very carefully. Especially, some logic as dynamic create instance function, such as dynamic create game level structure from a .json text file. The situation will become even worse if those logic are wrapped in some pre-built .dll (third party library). Some extra work need to be done to address such problems.

Others

For other settings that not mentioned here, just take the default values. Most of time, it will works.