A word of caution as the restrictions of WebGL development continue to be underestimated, or not even considered to begin with.
Here’s a rundown of things you NEED to sign off on before you go forth creating a WebGL enabled application.
WebGL Platform Notes
Please do take the time to read Unity’s WebGL Platform pages - all of them! These contain up-to-date information on the current level of limitations, restrictions and workarounds for WebGL.
WebGL Rendering Fidelity
Roughly speaking, WebGL 2.0 graphics is OpenGL ES 3.0 or in other words: it’s using technology from 2008! WebGL graphics are as brand new as “It’s an iPod, a phone, an Internet mobile communicator” aka the literal iPhone.
And it will stay this way for years as WebGPU is in its infancy and will take years to become mature and stable.
That means you can expect the visual fidelity of a WebGL application to match that of a 15-year old mobile device! Don’t expect too much! Specifically, don’t expect WebGL to run anywhere as fast as the editor can, and more so if we’re talking mobile WebGL.
Be sure to try some of the play.unity.com games to get a feel what you can expect. Note that games which do not make use of any sort of lighting/shadow or postprocessing effects are likely targeting WebGL 1.0, an even older tech. As of Unity 2022.3 WebGL 2.0 is the default.
Each browser will #§$*&§! with you
You have to consider that every browser, on every platform, is a platform in and of itself. There is no guarantee whatsoever that whatever works well in Chrome will work just as well in Firefox. And whatever works great in Firefox on Windows may be quite different from Firefox on Linux. Let alone mobile browsers.
For a desktop WebGL app, you have to test your build on at least Firefox, Chrome, and Edge (although that is technically now the same as Chrome).
For an Android WebGL app you have to test on the vendor browser (ie Samsung Internet) and the most popular alternative, typically Chrome and maybe Firefox.
For iOS WebGL at least you only need to test Safari, since every other browser is also forced to use Apple’s WebKit.
Needless to say, creating a WebGL app that works on both Desktop AND Mobile is among the most grueling, time-consuming projects you can indulge in.
WebGL Loading Times
Since WebGL is a slow platform (more on that below), you may see unexpectedly long loading times. While these work on desktop, they’re not to be published.
When was the last time you were waiting for a web app to load for more than 20 seconds? Right. You can’t even remember. You never wait this long.
Somehow, this is what it is on the web - we’re used to things going instant. If the streaming service is buffering for over 5 seconds we’re already aggravated! 10 seconds and we’d rather reload the page!
Which brings me, again, to iOS Safari. It is one of the most stringent, punishing browsers for a WebGL app. If your app blocks the main thread for too long, it will get killed. Yes, even while loading and within 15 seconds according to Apple’s own example. And if that weren’t enough, each browser tab gets at most ~500 MiB of memory to work with on many devices (currently those with 2 GiB of memory).
So if WebGL 2.0 wasn’t enough a limiting factor on visual fidelity, you cannot even make up for it by loading high resolution textures. No, in fact, you will have to severely downscale all assets in order to keep the loading time in check!
WebGL is single-threaded
For the time being, as of Unity 6, there is only an experimental C++ multithreading layer available. But other than that, every bit of code runs on a single CPU thread.
This can be quite the bottleneck in ways that come unexpected because many of Unity’s own systems are using background threads under the hood, most prominently rendering. So some things that work perfectly fine on Desktop will hit your app much harder in terms of performance when it runs in the browser.
The Browser Sandbox
Speaking of browsers: their primary utmost concern is security, safety, integrity. Thus they will not allow your app to access the file system.
You cannot simply File.WriteAllText() and similar methods in WebGL. That means you cannot provide users access to files that the application writes. Nor can you ask the user to upload a file to the app. At least not without writing a Javascript interface for this functionality.
Or using a hack where you can indeed open a Windows File Open/Save dialog - but of course this means the Web app will only work on Windows but fail to run on any other OS.
The PlayerPrefs save size is limited t 1 MiB. Although you shouldn’t be saving this much in PlayerPrefs to begin with.
WebGL Multiplayer limitations
If you plan on making a networked WebGL app, here’s a few things you need to know:
- WebGL networking runs through WebSockets (TCP), typically causing higher latency and more traffic
- WebGL apps cannot play “peer to peer” or host games, they can only join as clients to either a desktop-hosted game or a dedicated server
- The server or host must be configured to use WebSockets in order to enable WebGL clients to join. This means that if this particular server intends to allow cross-platform play with WebGL clients, everyone on that server will have to use WebSockets too.
On top, if you intend to create a couch multiplayer game, you ought to test carefully with every browser since gamepad support is all over the place. You can likely only use basic gamepad functionality, and multiple gamepads may not even be possible.
Building WebGL Apps
The first time you make a build, it’ll feel like making an Unreal build. Expect the build to take 20, 30, 40 minutes or more - depending on build options. Successive (incremental) builds will be noticably faster but will still take minutes. Unfortunately, you may have to “clean build” from time to time, particularly if there are any build, deploy or load issues.
Some Player Settings greatly affect performance, build time and memory usage. It is mandatory to get acquainted with the Player Settings respectively to play with them to see how far you can take it. Debug / development builds are the fastest but also consume more memory.
Don’t obsess with build output sizes or the build report, the latter only reports uncompressed sizes. The size of your final build is not necessarily reflecting or affecting its load time or memory usage.
Be prepared to make builds with an empty project to confirm any issues, such as not being able to run the built app on your webserver or itch.io with compression enabled. And similar such things. It’s always best to confirm whether the issue is general in nature, or project specific. Although it will eat into your time.
Always use the latest editor version. For WebGL in particular I would go so far as to recommend the latest Preview versions, not necessarily the LTS. But in either case ensure you try the latest patch release if you run into any inexplicable issues. This is because WebGL development keeps making big strides with every new Unity version.
Use Unity’s WebGL Publisher
The WebGL Publisher is the best part about WebGL development. You click build, grab a coffee / tea / coke / cake, and next thing you know your build is up and running on play.unity.com.