This was raised in another thread by someone, but I’ll ask it in its own thread - is it possible to split Unity engine code from the main .js code file ?
The final .js file contains all code (including user code, runtime libraries and engine code).
If the engine code is the same for a given version, it could be possible to separate that from “user” code, and host it separately, such that it will be cached and not downloaded every time.
The truth is that it is not really technically feasible right now, but more importantly, would buy you very little at the moment. The problem is that we could not use stripping on such a shared runtime, as a stripped runtime would only work with the content it was stripped for, and that it means that for games to have a runtime “cache hit” they would have to be built with the exact same version of Unity, making the benefits of such a shared cached runtime rather small (likely outweighed by the issue of not having stripping).
But isn’t the engine modular, e.g. physics 3d, physics 2d, audio, core, input, particles, animation, rendering 3d, rendering 2d as separate modules of the engine. I know that stripping could get down to individual methods and classes but if you used a modular/granular approach you would in theory only need to host the game play code and a loader to draw down the needed modules?
In a way external modular components would mean that older WebGL games can benefit from future improvements to the engine without needing a rebuild, making WebGL builds much closer to the webplayer in size and benefits.
And if there is a way for browsers to cache the components, WebGL builds would match and arguably improve* upon the webplayer.
No need to install plugins, so friction free for the end user, and auto updating to the latest build.
Providing a stable, dynamically-loaded shared engine library shouldn’t be significantly harder than it is to provide one for the webplayer, and I think it will have to happen at some point.
However even if the technical hurdles were surmounted, it would probably not help right now because a large portion of the startup time is the browser parsing the code, and until the browsers get better at that or cache the results, embedding a huge unstripped engine library in your game - even if it’s a standard module shared with other games - will mean your game takes even longer to load and requires a lot of memory.
When the browser asm.js support improves, when they start using bytecode, when they cache the parsed asm.js bytecode, then maybe dynamic loading a shared engine module will be viable. Judging by what I’ve read, Emscripten’s support for dynamic loading is a bit flaky too at the moment, so that needs to mature as well.
My understanding is that asm.js is designed to use a subset of javascript that makes it easier and faster to compile.
But modern Browsers take the javascript and depending on how often it is called compile it to ‘near’ native code. So in theory as long as the browser caches reused javascript modules and their Just in Time or Ahead of Time Compiled ‘nearly’ native code then the time to download and run other WebGL games that use Unity would be minimal after the first games are played.
And once enough games have been played to compile the main modules of the engine subsequent games should be faster still.
Of course updates to the engine will create slow downs but the use of CDN’s and or relationships with browser developers to auto download and cache the engine with updates could circumvent this a bit.
Is this possible yet? For us, it would be super useful, as we host multiple games on our website and expect a user to play multiple games per day – we can have them all using the same version of Unity with no issues, and this will save the user from downloading 10+ mb of engine code (if it’s about 5mb per game and they play 3 games a day).
It looks like the new Webassembly (wasm) system has dynamic linking so this could be a viable approach.
wasm should be out early next year, but we would need confirmation from the developers that this is a viable option (there could be technical problems and/or performance issues).
I came here after googeling for the exact same thing as mentioned in the thread (see: https://www.google.com/search?q=splitting+unity+webgl). I’m not an expert with emscripten and wasm so I’m not sure if this is technically possible. But splitting the code would be great for several reasons. For us it would be beneficial because “time to first interaction” could be lowered a lot. We don’t need the whole code upfront. And for most of our users it would be ok to wait some (milli)seconds for (lazy) loading one feature. I think sending only the needed resources to the client and lazily fetching the rest is actually way to go on the web (although paradigms in the web change quite frequently).
I think waiting for browser vendors takes a loooot of time. Furthermore the usage of the web changed a lot and there are many users with devices with low computational power. So I don’t think that performance issues are solved magically by faster CPUs/GPUs, better browsers, faster internet connections etc. It is interesting to read how Google thinks about the web as an application platform:
Sadly we are experience the issue “so long that many users simply give up” with our Unity build as well. So splitting up the code to provide a great perceived performance for the user could help us a lot.
Is splitting up the code feasible right now? Can something similar like the PRPL-pattern be implemented with Unity? I know that a Unity game is very different to most of the common webapps/sites but the users do not. They expect everything to load as quickly as their favorite webapp. Would be great to see if someone has implemented a efficient Unity build for WebGL. Especially for mobile users.
Yes, this would be amazing. Here’s our insane approach right now:
We have around 50 different small games the user can play, and they’ll play around 5 each time they go to the website. We have a CI system that listens for code pushes to any of these 50 games, and when there is one it will create a temporary project that has all the source code from all 50 games (but no assets), then that gets built. Since our games are small, 50 games worth of code is about 2mb, whereas the Unity engine itself is 6mb. So it’s a pretty small difference.
Then, when the user hits the page, we load the “all code app” in the background (in a hidden element on the page), and when the user actually tries to load a game we load an asset bundle with the scene, images, etc. and that only takes a couple seconds.
So it’s kind of like we separated the engine code. The major issue here is that updating any game means we need to update this whole thing, forcing a whole new download. Also, your website must use single page tech – the moment the user goes to a different page the engine will be unloaded.
Another option I’m looking into is to use MoonSharp and write all the game logic in lua. It will require making a lot of base C# code, so we’ll see if that turns out to be useful.
Like i use the asset bundle also, the stripping code is useless for me because the scene used to build my WebGL game contain only the code for load the asset bundle. For me a simple listbox in the editor where we can select/unselect what we need (physics,particles, animation ect …) would be the best solution.
With old unity (using this with 5.4) you can make the game build include the necessary parts of the engine by having dummy objects with the components you use. E.g. add some object with Terrain component which is invisible and does not use data, so that your actual terrains from assetbundles work.
But IIRC the new ones can detect it from the bundles at build time, I think it is already in 5.5. I guess need to put the bundles somehow available to right folder or so for unity to find them.
Unity 5.5 allows passing an assetBundleManifestPath to the BuildPlayerOptions parameter when using BuildPipeline.BuildPlayer. When this is used, Unity will make sure that any code used by Assets in included AssetBundles is not stripped.
Is there any update on splitting up the engine and game code? Seems like you guys are just waiting for WebAssembly at this point, but this (very necessary, in my opinion) step of isolating the engine code so it can be cached still needs to happen. Is it on your timeline at all? Any ideas when it will arrive?
I think your estimation of the benefits of stripping is low. Using the same version of Unity for multiple games is no big deal (and something we already have to do), so caching the engine is a huge savings when the user is loading 5 games in a session.