Stripping common Unity javascript from builds

Hi !
Could it be possible to extract javascript code related to Unity engine from the game itself and host that common javascript on any CDN server? If that could be done, it would reduce significatively the build size and allow faster downloads since that javascript libraries could be cached by the browser (like jQuery and other “standard” javascript libraries)

Just a guess.

1 Like

This is a pretty common question.

Unfortunately, in practice, the benefits would be rather limited (and potentially end up being a negative).

Unity WebGL saves a lot of space by stripping the engine to include only the code for the unity classes used in your project, by which we can bring down the compressed code size of a simple game to something ~3MB. If we were to share the engine with multiple games, we could not do that, as other games might use different classes, which means the size of the engine would be more like ~10MB. Also, for this to work, all the games would have to be built with the exact same version of Unity, which is rather annoying when one of them needs some bug fix from a newer version or something.

wow, just 3MB? That’s impressive and justifies not having to strip that code… I thought a greater part of the build size was related to Unity (+30 mb in my project) because the web player build takes less than 3 mb in total, so I thought the binary compressed form of the WebGL should take a similar amount of space (well, more because it’s not binary but…). I’ll have to take a closer look to which assets/plugins are taking so much space. Thank you.

please i have a webgl game that i need to be around 9mb but is currently 32.3mb… i have stripped the build of all things possible and my game is just a simple UI game… loading time is very poor and assigning a total space of 64mb gives a too large exception on a few mobile browsers. please i read from top eleven’s docementation they were able to get a 9mb build size and am wondering how they could do that.

Most if your game are going to be art assets and not code size. After you finish a build go to Build Report and take a look what is contributing to your build size (the build report is a preview feature, might not always work).

Best thing to recommend is using asset bundles heavily so you can get a really small startup scene and then start loading the the parts of your game that you need on demand.

So asset bundles is the only way to go… that means a total overhaul of the entire project. Thanks but i would say i want to disagree with the idea of the art assets, i used the minimal requirements for each png asset attached to the game panels. i would like you give the demo a try at ( loglords.com )… i would really love to hear a professional opinion as this size has been the issue with loading time and browsers. thanks

So how many of the 33MB are in the code file and how many in the data file?

Your game loading looks ok, but it then crashes because it runs out of memory (Chrome, 64bit) so you need to raise the memory limit or decrease the usage. See for example this post https://blogs.unity3d.com/2016/09/20/understanding-memory-in-unity-webgl/ about how the memory works.

Not sure my opinion counts as “professional” but the fast you show the player some progress the better. Hence the tip of using a small loader scene to go first and then load the rest on demand.

Thanks, Yes i got the same out of memory exception. i managed to reduce the files size to 14mb, 9mb of data file and 4 of the code but if i increase the total size to 64mb, its not working on 32 bit browsers (memory allocation issues). i read somewhere on gamasutra that adding -gz to the links in index.html increases loading time, i did and am getting a syntax error on the javascript console. i am currently using 5.5.0

Update:
I have resolved the syntax error i, i removed the -gz… i have a 64 mb total memory size and the game has been running for two hours now without crashing on chrome (mobile and windows), can i make it any less?
I also have a load time of between 10-15 secs on first load and 3-5 secs on next, i just need to get the player engaged while the screen loads. But i noticed the display isn’t that crisp on mobile, is there something i can do to optimize that and my keyboard isn’t coming up too on mobile… thanks for the help.

You can also try using the brotli compression (in Player settings) if you haven’t already. It is already supported by Chrome and FF (in unsupported browsers it will be decompressed using fallback JS) and will give you some size gains, how much depending on content.

You can try honing in on the memory you need to set using the memory profiler (see the linked blog post).

First: we don’t support WebGL on mobile yet.

There is a bug about “crispness” against chromium https://bugs.chromium.org/p/chromium/issues/detail?id=521364 which might be something you are seeing.

Can you submit a minimal test project as bug report (see Unity QA: Building quality with passion) with the keyboard not coming up on mobile?

I would do just that, thanks. I ran the new build on several systems and they all seem fine with the total size of 64 mb. Noticed the webgl canvas wasn’t displaying properly in safari and some chrome so i opt for a full browser view alternative in index.html but couldn’t get it to work too.

Also the loading bar is not working, seem broken. It doesnt show the load progress at all.
also i got this exception in the javascript console:

UnityLoader.js:1 GET http://loglords.fansbox18.com/llweb/Release/llweb.mem 404 (Not Found)
LoadCompressedFile @ UnityLoader.js:1
(anonymous) @ UnityLoader.js:1

Please i don’t understand what this means.
You’ve been of tremendous help. Thanks

I like the idea of splitting the code. I don’t think it is negative at all. I agree with @jonas-echterhoff_1 that a generic build of the Unity engine for everyone makes no sense. Many JS frameworks split the code into two files. One for the libraries and one for the business-logic-code. If we do this also for Unity this would lead to an engine-file and a game-file. Of course the engine-file is different for every Unity project and also different if the game-file requires different things from the Unity engine but there could be cases were only the game-file changes and then the user only needs to download the new game-file because the engine-file would be cached. If the game-file changes the engine-file, the user has to download both files of course. The JS frameworks do cache-busting by fingerprinting. They basically attach a hash to the filename. This logic could work for Unity too or is my point of view too simplified?

EDIT: found a thread about splitting the code even more, see here: https://forum.unity3d.com/threads/splitting-up-engine-javascript-from-game.321797/ seems like WebAssembly will be maybe solving all these problems in the future

@stephanwinterberger this sounds like an interesting approach. @Schubkraft do you think something like this is feasible and would this make sense for a Unity game?

Technically it would work but not sure about the benefits of this approach.

As I said, caching could be a benefit. But I’m not sure how tight the business logic and the engine code are tied together. If every change in the business logic results in a different version of the (stripped) engine code this would make no sense because the user would always have to download both files again.

Maybe two smaller files could give more flexibility to the developers. They could maybe load the two files on different places of their website and therefore the perceived performance could be improved (shorter UI stalls etc).

Theoretically I see benefits but I’m not sure how this would work out in a real world example.

@Schubkraft does this makes sense for you?

Making the webgl load as full browser view seem to make the loading faster. My app now loads in less time than the previous time. i hope unity looks into this in upcoming versions.

what do you mean? compared to what/when?

I meant the build loads faster… sorry for confusing you… please i’ll like my webgl to always change browser to landscape. please is there a way to go about it from the build folder assets