Streaming Asset Loading Outside of Babylon to Prevent scene Lag

I have a scene that grows in complexity as a user explores.

Babylon seems to be single threaded, so you can’t load assets (models, textures) while the scene is running or the engine “freezes” while the asset is being loaded.

What I am going to ask is probably ridiculous, but loading times for websites drive me nuts, like not a little nuts but full on crazy. Additionally, depending on where the user is interacting within the scene, they may not need to load most of the assets, so I hate to waste a users time loading tens or hundreds of assets they will never use.

With the single thread limitation in mind I got to wondering if it was possible to side load assets outside of Babylon - so they have their own thread and don’t lag the engine - then give Babylon access to them once loaded.

I have never done anything like that, don’t really know where to start (if it is even possible) but did find an example in the old forums of a texture being loaded outside the engine then utilized to provide a better progress indicator. I was wondering if other assets, such as models, could use a similar method?

Has someone already done this? Dev gods, is loading things outside of Babylon but still in the browser, then passing the loaded asset to Babylon to use even feasible?

I’m not aware of anything inside Babylon supporting this, but you can use Web workers with XHR or fetch requests and then load them using the data: syntax:

Please ignore the comment about the textures, for your use case you could just embed them. They will even work IIRC if you give the call the correct directory and don’t change mesh names.

This is the system we use (except we’re not using web workers yet, but that’s easy to add). There’s a bit of a setup cost, but it shouldn’t amount to much more than 200 lines of Javascript. Our whole loading code is about 100 lines at the moment.

edit: If the Babylon loading code is the cause of the lag, then you can also try spreading it out using requestAnimationFrame (only load 1 asset or mesh (using 1st parameter to select the mesh) per frame) in combination with a queue where all the json/gltf files that were downloaded are placed. Probably best implemented with promises. Also don’t do everything in the callback, I have found that complex callbacks like this are also often a source of lag.

Another idea (that we might implement too) would be to run a second NullEngine in a web worker and load everything through that one. I’m not sure if Babylon supports this though.

It has been over a year since I asked this, or really did anything serious with Babylon, darn heart decided to give me trouble and I had to take a break from all but dabbling in BabylonJS. Anyway, I want to revisit this question as I am restarting what I was working on.

Since almost a year has past, is there a more modern way of streaming assets than the post above? I have been lurking the forums to try and keep current and could have sworn I saw a post about using a null engine to load assets in a separate thread, then somehow pass the loaded assets to the active canvas version of the engine, but can’t find it now.

I don’t know if that is a better procedure than what is outlined above, both are likely above my coding ability with out an example right now - its been a while - but with 4.x out now I figured I would ask again. What is the most efficient way of loading assets on the fly while not lagging a user already in a scene while avoiding a long load time in the beginning to preload all assets.

This is resolve around Javascript running on a single thread.
So the simple answer is still: no it is not possible.

Longer answer:

  • You have to determine what is hitting your CPU. Is it big assets, big textures?
  • If you have a lot of assets, a good idea is to dispatch the loading across multiple frames (like one model per frame)
  • Same if you have a lot of textures

Ideally if you could repro your use case in the Playground we could brainstorm together to find creative ways to deal with your issue