Common WebGL Issues


On WebGL, it is not possible to change the resolution using Unity's APIs (e.g. Screen.fullScreen), use the methods in ⚙️ PerformanceKit instead.


Unity only supports the main thread on WebGL as per their documentation. This means you can't use Async/Await operations, and you need to perform these on the main thread instead. One way to do that is by using Coroutines.

Shader pragma target

Games on Pley can only use the Shader Pragma Target 3.5 or lower since that is the highest one supported on WebGL 2.


Your game should avoid using Unity's CursorMode.ForceSoftware or otherwise rendering the cursor manually, as opposed to letting the browser handle it.

Cursor responsiveness is paramount for performance, much more than the actual FPS of your game. Letting the browser handle the rendering will minimize latency and drastically improve the perceived responsiveness of your game.

IL2CPP code stripping

If your game uses C# Linq expressions, in some situations IL2CPP code stripping might prevent you from building your game.

To solve that add a link.xml file in the root of your Assets folder with the content below.

<assembly fullname="System.Core">
<type fullname="System.Linq.Expressions.Interpreter.LightLambda" preserve="all" />

Setting the frame rate

Browsers do not have support to directly control the frame rate, which means that Unity's Application.targetFrameRate is not a good idea. If your game sets it to anything else other than -1, Unity will try to achieve the desired frame rate emulating the browser render loop which more often than not results in a decreased or unstable frame rate.

No multithreading

Multithreading doesn't yet work very well on Unity's WebGL and we recommend that you do not use it. Instead, do async operations on the main thread with the help of coroutines.

More resources

For more information regarding WebGL we recommend the following articles:

WebGL performance
Shader Compilation Target Levels
WebGL Browser Compatibility