Got stuck in a performance issue in Unity WebGL that whenever my asset bundles are load, my unity game gets freeze for some seconds/minutes. I know that unity is not thread-safe and it is based on a single thread but these statements are confusing for me. From the official sites/persons of unity:

Threads are not supported due to the lack of threading supporting in JavaScript. This applies to both Unity’s internal use of threads to speed up performance, and to the use of threads in script code and managed DLLs. Essentially, anything in the System.Threading namespace is not supported (Source Unity Docs 1).

Lack of threading support in JS? Does it mean it supports on the desktop?

Since WebGL does not support threading, and since HTTP downloads will only become available when finished, Unity WebGL builds need to decompress AssetBundle data on the main thread when the download is done, thus blocking the main thread. To avoid this interruption, you may want to avoid using the default LZMA Format for your AssetBundles, and compress using LZ4 instead, which is decompressed very efficiently on-demand. If you need smaller compression sizes then LZ4 delivers, you can configure your webserver to gzip-compress the files on the http protocol level (on top of LZ4 compression) (Source Unity Forum/Offical 2).

Here is saying doesn't support threading but the asset bundle is load in the main thread? Do it support thread? It sounds confusing to me.

WebGL does not support threads, so the Async operation is running on the main thread causing the freeze that you are seeing (Source Unity Forum/offical). Blockquote

Doesn't support thread but asset bundle loading in the main thread??

These statements are confusing for me? Do unity supports thread? If Not then, What is the main thread? Why unity repeatedly call that asset bundle is load in main thread? If unity doesn't support thread then how async/coroutine operation is performed?

Edit: Unity 2019.1 has released with this note WebGL: Added experimental multi-threading support. Do it means we can use thread now?

List of issues in unity-WebGL.

  • \$\begingroup\$ The main thread is the first thread; anything that ever runs on a computer has at least one main thread. \$\endgroup\$
    – Hobbamok
    Jan 30 '20 at 12:50

Unity does run multiple threads, but NOT in WebGL.

  1. Standard unity and most of it's target platforms that support multithreading will use multithreading. If you've ever had your game freeze and heard the audio continue to play, that's why. There's an audio thread, a render thread, a game logic thread, and I think a physics thread (but I'm not 100% on that). Concurrent game engine design is a complicated topic as I'm learning while building my own engine, so I won't explain how each of the threads work. What's important to know is you only need to work within the main thread. You can in fact write multithreaded libraries as long as you don't call unity functions. For example I wrote a library for parsing joycon input via bluetooth. This library runs on a seperate thread recording and time stamping inputs, then in Unity's update cycle, asks the joycon thread what inputs have come in.

  2. Unity's WebGL support is... lacking. While porting a major project over, I experienced many pains. For one, it does not handle audio correctly at all. Usually in audio your sound card is capable of outputting X number of voices at once. In other words, X distinct sounds. But many games have more than X sounds, so unity will mix sounds together into a single sound, and sometime just not play a sound all together. This is what the priority field in an audio source does. In WebGL it supports none of this, and if you play too many sounds at once, the audio will crash. Try writing a script that plays X audio sources at once. Increase X, build, run on browser of choice. Depending on browser and computer, that number will differ. The lowest I ran into was macbook. If you have many sounds in your game (like a bunch of units/characters screaming into battle) then you will have to write your own system, which is a lot of work. WebGL as you gathered also does not support multi threads.

  3. Asset bundle are basically necessary for WebGL. In a standard environment, you save the game on disk, then when you run, you load the required resources into RAM for quick access. In WebGL you ONLY have RAM. And you only get ~1GB. You can go more but you'll have compatibility issues fast. If you're making a game from scratch, plan for this. I advise making each scene an asset bundle. You can use unity's AssetBundleBrowser to do this. The docs are pretty inaccurate, but it will include the dependencies when you bundle it. If found the "build" button didn't work, so you can write your own script for it. I'll leave out the details because it's all easily googlable information, but it's hard to find what DOES and DOESN'T work, so I'm just describing my rough process. From there make sure each scene is less than ~750mb. Unity will need some space to run, and uses up some of your precious memory. If you're porting, you may have to compress the ever loving fuck out of your assets. Audio and visual. Follow unity's webGL guide for the type of compression. You can then use the loading screen to get your asset bundle. Use the AssetBundle API not WWW because WWW will load double the amount of memory, since it will download, THEN decompress. AssetBundle will decompress as it downloads, minimizing the memory spike. I can't put all the pitfalls of asset bundles in one response, but hopefully this will help with some of the more difficult problems I faced. Don't forget to keep track of how many audio sources you're playing.

  4. Finally, after all this, if you're not tied to Unity, I'd advise simply not using it for Web content. If you're starting a new project, and have little investment in Unity, go learn an engine designed for web. There's lots of JS game engines out there that will have far better support. WebGL in Unity is the forgotten child that gets kept in the basement. I'd avoid it if you can. But if like me, you find you have to, get ready for a long and tough ride.

  • \$\begingroup\$ My goodness! signficant things are in one Post, Thanks. Starting form the last point, sorry i can't avoid unity, actually a lot of work has done in that and our expertise are limited to unity. \$\endgroup\$ Apr 12 '19 at 14:29
  • \$\begingroup\$ Actually i have tried uncompress asset bundles as well but it same old game freeze. Once i read about it that decompression takes time that freeze the game. \$\endgroup\$ Apr 12 '19 at 14:30
  • \$\begingroup\$ You may find it interesting, stackoverflow.com/questions/55570170/… . Question is open for 100 bounty. \$\endgroup\$ Apr 12 '19 at 14:31
  • \$\begingroup\$ Actually the threads are also work sequentially (in the main loop) as @EdMarty answer suggest. Then why it make difference in webgl? \$\endgroup\$ Apr 12 '19 at 14:32
  • \$\begingroup\$ Yes they run parallel in other platforms. What makes webGL different is that the web platform as a whole is very different. Browsers are very restrictive for security/performance reasons. One of these things is multithreading. Imagine if Chrome let any old website run as many threads as it wanted. Your resources would be a disaster, and sadly people would blame their computer running slow on chrome, not the website. \$\endgroup\$
    – gjh33
    Apr 15 '19 at 15:50

What Unity doesn’t support in JavaScript is multiple threads. So there is only ever the single main thread of execution. If there were multiple threads, Unity would be able to run LZMA decompression on a background thread while the main thread is busy running the game. However, since this is not the case, it must apparently use the only thread of execution available, which cannot run the game during this time.

Coroutines are not implemented using threads, even when multiple threads are supported. Coroutines always run on the main thread. They use a special feature of C# (“yield return”) which lets you pause execution of a method and come back to it later. So Unity keeps track of all the coroutines it’s running, and goes back into them at the right time. A simple implementation of how Unity does it internally might look like this:

mainLoop() {
    while (true) {

runCoroutines() {
  for (coroutine in coroutines) {

Where MoveNext is the method that goes back into the coroutine’s code and executes it until it reaches the next yield instruction, at which point the coroutine temporarily suspends execution until the next call to MoveNext.

  • \$\begingroup\$ Thanks for very informative post specially the code example. But your code suggest that all three functions are run sequentially, Not parallel or simultaneously. \$\endgroup\$ Apr 12 '19 at 6:40
  • \$\begingroup\$ So do Unity desktop have multi thread? as you said js don't support multi thread? if unity desktop have multi thread then what they are? \$\endgroup\$ Apr 12 '19 at 6:41
  • \$\begingroup\$ Unity desktop runs in a multi-threaded environment, so you can make arbitrary threads to run your own code. Unity also has some of its own threads, including the loading thread (for reading things from disk, creates new objects, etc.), and various worker threads that can do arbitrary things Unity needs to do. This is also where C# jobs come are run. I don’t remember if it also has a separate dedicated render thread. The code does run sequentially. There is nothing running in parallel. \$\endgroup\$
    – Ed Marty
    Apr 12 '19 at 13:22
  • \$\begingroup\$ Means, these all threads(if you provide any source link of this) are available in desktop but not in webgl as javascript is single threaded.? \$\endgroup\$ Apr 12 '19 at 14:19
  • \$\begingroup\$ Yes. Everything happens in a single thread in webgl and on multiple threads on other platforms. \$\endgroup\$
    – Ed Marty
    Apr 17 '19 at 14:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .