# How to pre-load (lots of) textures in a backgroud thread smoothly

**URL:** <https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176>\
**Category:** Questions\
**Created:** [May 27, 2021, 7:35am UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176 "2021-05-27T07:35:18Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Escobar](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/escobar/32/2726_2.png) [@Escobar](https://forum.babylonjs.com/u/Escobar)\
**Post date:** [May 27, 2021, 7:35am UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/1 "2021-05-27T07:35:18Z")

</div>

My intention is to download the files (cubemaps) to cache them for further usage I don’t need to have them in memory, just download them to make a fast load.

I already managed to make that preload with two different methods:

- Adding addCubeTextureTask and calling load() in the assetsManager.

- Using a recursive function that creates a promise and once a texture is loaded it gets disposed and tries to load the next one.

Unfortunately both options are lagging the navigation a lot, is there any other alternative?

Thank you for any tip!

---

<div class="post-metadata">

**Author:** ![labris](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/labris/32/12576_2.png) [@labris](https://forum.babylonjs.com/u/labris)\
**Post date:** [May 27, 2021, 7:52am UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/2 "2021-05-27T07:52:25Z")

</div>

Do you experience lagging while loading, after loading or when changing the textures?

---

<div class="post-metadata">

**Author:** ![Escobar](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/escobar/32/2726_2.png) [@Escobar](https://forum.babylonjs.com/u/Escobar)\
**Post date:** [May 27, 2021, 9:11am UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/3 "2021-05-27T09:11:40Z")

</div>

@labris while loading once all the tasks have been completed it becomes smooth again.

---

<div class="post-metadata">

**Author:** ![labris](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/labris/32/12576_2.png) [@labris](https://forum.babylonjs.com/u/labris)\
**Post date:** [May 27, 2021, 9:51am UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/4 "2021-05-27T09:51:42Z")

</div>

Seems that the simplest solution will be to use loading screen until all needed assets are loaded, then hide loading screen - [Creating Custom Loading Screens | Babylon.js Documentation](https://doc.babylonjs.com/divingDeeper/scene/customLoadingScreen)

---

<div class="post-metadata">

**Author:** ![Escobar](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/escobar/32/2726_2.png) [@Escobar](https://forum.babylonjs.com/u/Escobar)\
**Post date:** [May 27, 2021, 11:31am UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/5 "2021-05-27T11:31:47Z")

</div>

I already have a proper loading screen working, but I know that I’ll need those textures later that’s why I try to load them in advance meanwhile the viewer is already running (with the actually needed textures already loaded).

---

<div class="post-metadata">

**Author:** ![labris](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/labris/32/12576_2.png) [@labris](https://forum.babylonjs.com/u/labris)\
**Post date:** [May 27, 2021, 12:39pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/6 "2021-05-27T12:39:45Z")

</div>

By default, all texture contents are cached by the engine, so if you load the same texture twice, it will be instant (and resource will be shared to save memory).  
This is one way.  
Another is to indicate that you want to cache the resources associated with your scene/game inside the local IndexedDB of the browser - [Optimizing Using Cached Resources | Babylon.js Documentation](https://doc.babylonjs.com/divingDeeper/scene/optimizeCached)

---

<div class="post-metadata">

**Author:** ![Escobar](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/escobar/32/2726_2.png) [@Escobar](https://forum.babylonjs.com/u/Escobar)\
**Post date:** [May 27, 2021, 6:59pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/7 "2021-05-27T18:59:00Z")

</div>

That was exactly what I want to chache them even before being used for that I tried to load and dispose them to make a fast reload when is the texture is required.

Thank you for your time.

---

<div class="post-metadata">

**Author:** ![Mark\_marshall](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@Mark\_marshall](https://forum.babylonjs.com/u/Mark_marshall)\
**Post date:** [May 29, 2021, 9:44am UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/8 "2021-05-29T09:44:15Z")

</div>

Hello[,](https://www.mybalancenow.review/)  
thanks for sharing your concern.  
whereas stacking once all the assignments have been completed it gets to be smooth once more.

---

<div class="post-metadata">

**Author:** ![Escobar](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/escobar/32/2726_2.png) [@Escobar](https://forum.babylonjs.com/u/Escobar)\
**Post date:** [May 29, 2021, 4:09pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/9 "2021-05-29T16:09:13Z")

</div>

I’ll try to summon the great guru @Deltakosh 🙂

---

<div class="post-metadata">

**Author:** ![br-matt](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/br-matt/32/22436_2.png) [@br-matt](https://forum.babylonjs.com/u/br-matt)\
**Post date:** [May 29, 2021, 6:08pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/10 "2021-05-29T18:08:13Z")

</div>

@Escobar there is an idea @Evgeni_Popov posted in [Throttle processing power/bandwidth to keep stable FPS during loading - #15 by Evgeni\_Popov](https://forum.babylonjs.com/t/throttle-processing-power-bandwidth-to-keep-stable-fps-during-loading/20580/15)

TLDR: moving as much of texture loading into a worker as possible. I am still working on this myself, since had other fires pop up that took me off that branch

---

<div class="post-metadata">

**Author:** ![Escobar](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/escobar/32/2726_2.png) [@Escobar](https://forum.babylonjs.com/u/Escobar)\
**Post date:** [May 31, 2021, 5:48pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/11 "2021-05-31T17:48:57Z")

</div>

> [@Throttle processing power/bandwidth to keep stable FPS during loading](https://forum.babylonjs.com/t/throttle-processing-power-bandwidth-to-keep-stable-fps-during-loading/20580/16):
>
> because we are constantly streaming in new geometry. For now, we limit the number of textures that can be processed a frame and give a breather after each one, that helps performance a lot. I have put the glb download into a worker and transferring the array buffer over which helps but not much.

How did you managed to do that? I tried by moving

`BABYLON.Tools.LoadFile(textureFile, function () {});`

into a worker and it gets downloaded but it doesn’t speedup the loading time 😒 placing a loadcubetexture there do not help since I cannot send scene as reference to place the texture in that reference, and probably making a secondary copy do not help with loading times neither.

Thank you for your time, I’ll owe you a beer for each useful tip!

---

<div class="post-metadata">

**Author:** ![br-matt](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/br-matt/32/22436_2.png) [@br-matt](https://forum.babylonjs.com/u/br-matt)\
**Post date:** [May 31, 2021, 7:22pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/12 "2021-05-31T19:22:39Z")

</div>

> [@Escobar](#):
>
> How did you managed to do that? I tried by moving
> 
> `BABYLON.Tools.LoadFile(textureFile, function () {});`
> 
> into a worker and it gets downloaded but it doesn’t speedup the loading time 😒 placing a loadcubetexture there do not help since I cannot send scene as reference to place the texture in that reference, and probably making a secondary copy do not help with loading times neither.
> 
> Thank you for your time, I’ll owe you a beer for each useful tip!

More trying to solve the frame lag caused by loading textures during runtime. For workers, only tried downloading a whole glb and transferred back the buffer for Babylon to load. That does not help the lag much. (I think because textures are then further extracted on the main thread by SceneLoader)

I am not sure this will work for your setup if you are not using packed up glbs/a custom extension that gets hit. The thing that helped performance (somewhat) is slowing down how many/often the textures get processed by Babylon. Again, this might not be what you are after at all 😃

`loadMaterialPropertiesAsync` returns a `Promise.all()`

[p-limit - npm](https://www.npmjs.com/package/p-limit) used this library to create a limiter for all the texture load promises that get pushed in there.

---

<div class="post-metadata">

**Author:** ![gabrieljbaker](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/gabrieljbaker/32/12670_2.png) [@gabrieljbaker](https://forum.babylonjs.com/u/gabrieljbaker)\
**Post date:** [May 31, 2021, 7:56pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/13 "2021-05-31T19:56:16Z")

</div>

@FrameVRWill this might be interesting for us as we get into our asset load queues.

---

<div class="post-metadata">

**Author:** ![Escobar](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/escobar/32/2726_2.png) [@Escobar](https://forum.babylonjs.com/u/Escobar)\
**Post date:** [June 2, 2021, 6:33pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/14 "2021-06-02T18:33:54Z")

</div>

Here is my task.js code where oEvent.data is a Babylon SmartArray that contains the URL of each texture

> onmessage = function (oEvent) {  
> const suffix = [“\_px.jpg”,“\_py.jpg”,“\_pz.jpg”,“\_nx.jpg”,“\_ny.jpg”,“\_nz.jpg”];  
> for(var t=0; t\<oEvent.data.data.length; t++)\>  
> {  
> console.log("Background download: ",oEvent.data.data[t]);  
> for(var i=0; i\<6; i++)  
> {  
> const textureFile = oEvent.data.data[t] + suffix[i];  
> BABYLON.Tools.LoadFile(textureFile, function () {});  
> }  
> }

It downloads the files but unfortunately I didn’t get any performance gain as if “the scene babylon” doesn’t take advantage of “this babylon” download.

Maybe someone of you could use this code in your tests if you find it useful.

---

<div class="post-metadata">

**Author:** ![Escobar](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/escobar/32/2726_2.png) [@Escobar](https://forum.babylonjs.com/u/Escobar)\
**Post date:** [June 7, 2021, 12:15pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/15 "2021-06-07T12:15:29Z")

</div>

Btw loading textures with LoadFile using promises is speeding up the loading a lot but if I don’t use them in a Babylon Texture it seems that they are removed by the garbage collector and unfortunately if I use them in a texture the laggy loading appears again.

Any tip to avoid the gc to remove them?

---

<div class="post-metadata">

**Author:** ![br-matt](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/br-matt/32/22436_2.png) [@br-matt](https://forum.babylonjs.com/u/br-matt)\
**Post date:** [June 8, 2021, 12:49pm UTC](https://forum.babylonjs.com/t/how-to-pre-load-lots-of-textures-in-a-backgroud-thread-smoothly/21176/16 "2021-06-08T12:49:31Z")

</div>

Can you just hang on to them with a reference in an Object that you know sticks around ? Also then can release them by deleting the key, when you do want them cleaned up.

As long as you have a reference to a loaded texture in something attached to `window`( in its chain of references ), the GC should not clean it up.
