Are there any planned improvements to speed up the WebGL build process?

Could the WebGL build process be faster e.g.

Caching of build or intermediate files that have not changed since the last build.
Pre-building the current project in the background.

Ideally the WebGL build would be so fast we could use it in the play window.

So any planned improvements to speed up the WebGL and IL2CPP build ‘engines’?

Yes. In Unity 5.1, you will see:

-A new emscripten version, which has moved the complete process of optimizing the build from being JavaScript code executed by node.js to being a native executable, improving the speed of “Fast” or “Fastest” builds.
-Il2CPP improvements reducing size of generated code (and as a consequence improving build times).

here is work to improve the situation further on both our side (possibly making il2cpp be more incremental in it’s builds) and on mozilla’s emscripten side (they plan to eventually move everything to a native process, instead of the combination of js/python/native code we have now).

All this will improves the situation compared to 5.0, but will still be far from an ideal world with near-instant builds as we have on some other platforms (which I don’t think will realistically happen for WebGL any time soon, tbh).

5 Likes

@jonas-echterhoff_1 Great as I think il2cpp and emscipten are both processing a lot of code that does not change between builds e.g. engine code or code not changed between builds so you could get an amazing improvement on build speed.

For the near instant builds just cache and build the bits that have changed in the background.

And if you go modular with a CDN hosted modular Unity webgl build we would only need to build the code we write!

I think that engine code already comes in some pre-processed format (.bc file - bitcode?)
2100411--137528--upload_2015-5-5_23-58-1.png

Good find.

My point is that it could be pre-compiled to asm.js.

Then it could be hosted on a CDN service as a super fast downloadable and cacheable javascript library.

Massively reducing the build size and speeding up the Unity WebGL gaming experience.

IIRC it was mentioned that the CDN approach wasn’t ideal as it would mean you couldn’t apply stripping, so you’d end up with a much bigger initial download.

But once downloaded and cached all other Unity games would be quicker to download and start

Also ideally the browser would cache the compiled javascript library allowing things to start faster.

As with the concept of stripping, you could release the build as asm.js modules e.g. Physics 2D, Physics 3D, Rendering 2D, Rendering 3D, Core, Input, UI and Particles.

Then only the needed modules could be downloaded.

Actually could that be faster as I think browsers can multithread content downloads?

It would be nice if the browsers allowed commonly used libraries and modules a similar status to plugins, where the browser would update and AOT compile them in the background from startup.

All other Unity games made with the exact same version (including weekly patch release) of Unity, that is - which is greatly decreasing the benefits, unfortunately, as the chance of having a “cache hit” between two games is much lower.

In theory, yes.
In practice, it is not quite that easy. I have actually tried a setup exactly like you described a while ago, and dropped the idea as not being feasible.

The thing is that dynamic linking like that comes with a cost which is not insignificant.

  1. We could not strip at the same granularity as we do now.
  2. The linker cannot do inlining between modules, which can cost performance
  3. A lot of APIs need to be called across modules, which mean more indirection, and results in slower calls,
  4. Exposing APIs to be called across APIs means symbol names need to be preserverd, which means the code can be less minified and will be bigger in the end.

I might revisit the idea in the future, but I currently don’t think that much can be gained that way. Also, IIRC, asm.js does not currently support dynamic linking anyways.

Well, yes, but that won’t magically get you more bandwidth.

@jonas-echterhoff_1 OK great response thank you for taking the time to explain the problems with my idea.

  1. How much of a difference does stripping make?
    I’ve just done a simple test with a scene with and without stripping and the js file unstripped was 25,564 kb and stripped 22,362 kb a 13% reduction uncompressed or 5,305 kb down to 4,629 kb compressed so it’s saving about 1-3 mb in size.

And it looks as though most games I make weigh in over 22 mb unzipped (tested with empty scene) just for the game js file. So to me it looks like a single 22 mb js file cached for Unity would allow all subsequent Unity webgl games to download and start faster.

I think the way the webplayer worked is that you could get patch release versions but they were just for that patch and point release versions were for everyone.

2/3 OK I suppose it will be slower but have you profiled this to see what the impact in performance actually is? Would it be a massive drop say from 60fps to 30fps or just a few percent.

  1. How much bigger a few extra bytes for the strings adding up to a few kilobytes in the js files. I doubt we are talking megabytes here. Could you use a link cross module minifier to reduce this?

Sounds like asm.js and javascript needs a few updates to improve it’s ability to link.

If I’m correct in understanding the problems then it would appear until javascript and asm.js are improved it’s the linking between modules at runtime that is the issue. And to get around that you provide a single asm.js for our unity WebGL games.

But what if the modules were designed to be combined into a single asm.js file by the browser at run time?

This would probably be extremely tricky to do but is theoretically feasible, and probably something for the guys at Mozilla working on asm.js to look into.

But I would revisit these issues and profile their impacts as I think the problems you have raised may be a lot smaller although more technically challenging than the elephant in the room that is the core 22mb download needed for each game.

In this space Unity is competing with lighter weight web based technologies that do take advantage of CDN servers and libraries that may not be as fast (initially) as Unity but with time as browsers improve will become comparable.

OK I’ve had a look at a few three.js + ammo.js demos and a Playcanvas game and it looks like they (without caching) can weigh in around the 15-20+ Mb level. A bit below Unity’s 22+ Mb level.

You can argue that with caching a Unity game will gain the same benefit, however as long as each Unity game needs it’s own cache and other games or sites rely upon a common set of cached js modules they will gain the upper hand (load faster).

Most users especially ones looking for quick games in the browser will choose the games faster to load.

OK think of it this way say I have a set of games on my website (I do actually all webplayer http://arowx.com) they consume bandwidth as people play them but their core is common in the webplayer.

If I switch to WebGL even with stripping and caching each new player per game is going to have a potentially higher bandwidth hit than my games using the web player.

I have 20 games but what about Newgrounds/Kongregate/Wooglie/Itchi they are going to take a massive bandwidth hit if they take Unity WebGL games.

How long before they start recommending playcanvas, other CDN supported webgl game engines?

What if you just stripe code on the asset folder, leaving standard assemblies and Unity Engine untouched/precompiled?
What will be the effect?
Will it at least make sense during development?
Will it allow to reuse a runtime and move it to a CDN?

I don’t think so as the asm.js file for your game is all the code it runs.

Hi @jonas-echterhoff_1 !

When can we test those improvements? Does any recent 5.1 beta include the new emscripten version?

The latest 5.1 from the beta forum has the changes Jonas mentioned.

Good to know! Thanks. I’m now really interested in 5.1 :slight_smile:

it is still painfully slow in 2019.1.3f1

horribly so.

rendering a simple cube takes 30 minutes (on an ssd, i7, 8gb ram, mediocre gpu). The thing is, rendering a much more complicated scene takes 30 minutes too!