# Optimizing the render() call

**URL:** <https://forum.babylonjs.com/t/optimizing-the-render-call/29582>\
**Category:** Questions\
**Created:** [April 21, 2022, 12:57pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582 "2022-04-21T12:57:37Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![jjv360](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jjv360/32/20742_2.png) [@jjv360](https://forum.babylonjs.com/u/jjv360)\
**Post date:** [April 21, 2022, 12:57pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/1 "2022-04-21T12:57:37Z")

</div>

Hi, we’ve recently converted our app from Three.js to Babylon, however there are some users who are saying that they get a lower FPS in the Babylon version. I’ve been optimizing various things, but there’s one piece that I can’t seem to sort out… It seems that Babylon’s render() function simply takes double as much CPU, sometimes more, than Three.js’ one… Is there a way to optimize this? I’ve already tried everything in the [Optimize Your Scene](https://doc.babylonjs.com/divingDeeper/scene/optimize_your_scene) page…

To test this at the most basic level, I created two examples which both simply create 5000 cubes (going overboard to make it more obvious) and then renders them. On my machine the Three.js version renders at a consistent 13ms per render(), while the Babylon version varies at around 22-34ms per render()…

I have also tried using freezeActiveMeshes() and it brings it down a lot, but not all the way to Three.js’ level, plus we wouldn’t be able to use that anyway since as I understand it, it turns off the detection of which objects are in the frustum for rendering…

[BabylonThreeComparison.zip](https://forum.babylonjs.com/uploads/short-url/4BJANFLPSbrvEtrNxinCfpjpWNK.zip) (1.0 MB)

---

<div class="post-metadata">

**Author:** ![Cedric](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/cedric/32/2742_2.png) [@Cedric](https://forum.babylonjs.com/u/Cedric)\
**Post date:** [April 21, 2022, 1:01pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/2 "2022-04-21T13:01:11Z")

</div>

This is something that will interest @sebavan and @Deltakosh

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 21, 2022, 1:44pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/3 "2022-04-21T13:44:22Z")

</div>

I’m not an expert on 3js but one thing could help us here:

Can you drop here the 3js code and create a pg with Babylon code?

I want to make sure that we are comparing apples to apples

If this is the case we obviously have a bug somewhere and I’ll fix it faster than light:)

---

<div class="post-metadata">

**Author:** ![jjv360](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jjv360/32/20742_2.png) [@jjv360](https://forum.babylonjs.com/u/jjv360)\
**Post date:** [April 21, 2022, 3:00pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/4 "2022-04-21T15:00:09Z")

</div>

Hi, the code for both examples is attached in the first post. I wanted to make a playground, but I don’t think I can wrap a timer around the render() function from inside a playground, the playground seems to call render() on it’s own outside the user’s code…

---

<div class="post-metadata">

**Author:** ![kaliatech](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/kaliatech/32/13557_2.png) [@kaliatech](https://forum.babylonjs.com/u/kaliatech)\
**Post date:** [April 21, 2022, 3:09pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/5 "2022-04-21T15:09:20Z")

</div>

In case it helps, you can make your own render loop inside the PG with code like this:

```javascript
    //Override the playground render loop
    setTimeout(() => {
        engine.stopRenderLoop();
        engine.runRenderLoop(() => {
            console.log("render");
            scene.render();
        });
    }, 0);

```

Example:

- [BJS Playground - Custom Render Loop](https://playground.babylonjs.com/#RFGA4U#2)

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 21, 2022, 3:14pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/6 "2022-04-21T15:14:05Z")

</div>

ok bjs version: [Multi Scene Swapping with GUI | Babylon.js Playground (babylonjs.com)](https://playground.babylonjs.com/#RFGA4U#3)

---

<div class="post-metadata">

**Author:** ![jjv360](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jjv360/32/20742_2.png) [@jjv360](https://forum.babylonjs.com/u/jjv360)\
**Post date:** [April 21, 2022, 3:16pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/7 "2022-04-21T15:16:09Z")

</div>

Cool, looks like the render() timing is the same as for the non-playground example

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 21, 2022, 5:37pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/8 "2022-04-21T17:37:30Z")

</div>

Ok! so first thanks a lot for the feedback! It helps a lot

So first comment: The test as it is right now is a bit misleading because all meshes have the same matrix and then there is no activity on the 3js front where we do not spend time optimizing for this very specific case. A more “fair” comparison would be to use random position to avoid having the same matrix for all meshes: `box.position.set(Math.random(), Math.random(), Math.random())`

Then, you are not really comparing apples to apples as our material has more features enabled (`box.material.dissableLighting = true` has a typo :)). I would recommend using `material.freeze()` to get a comparable material

I updated the PG:  
[Multi Scene Swapping with GUI | Babylon.js Playground (babylonjs.com)](https://playground.babylonjs.com/#RFGA4U#5)

With these updates you should get much closer to 3js.

But now we hit the elephant on the room 🙂 3js and babylonjs are very different engines with different goals and philosophies. Here you are seeing one difference: bjs has a lot of features available out of the box, easy to use but it comes with a price: a small perf hit

We introduced the `scene.freezeActiveMeshes()` feature for this specific need: turn off all the bells and whistles to focus on pure rendering.

But you raised a good point: In that mode there is a missing point: we have no culling.  
Well…we HAD no culling 😉 Thanks to you we added the option with this PR:  
[Remove some unnecessary computations by deltakosh · Pull Request #12421 · BabylonJS/Babylon.js (github.com)](https://github.com/BabylonJS/Babylon.js/pull/12421)

Thanks again!

---

<div class="post-metadata">

**Author:** ![jjv360](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jjv360/32/20742_2.png) [@jjv360](https://forum.babylonjs.com/u/jjv360)\
**Post date:** [April 21, 2022, 6:05pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/9 "2022-04-21T18:05:23Z")

</div>

Thanks, that helps a lot 👍

But I think I don’t understand what an “active” mesh is, then… I thought active meshes were the ones that were in the frustum and so get rendered, but is it something else?

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [April 21, 2022, 6:31pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/10 "2022-04-21T18:31:51Z")

</div>

when you call freezeActiveMeshes you are forcing BJS to stop doing a lot of stuff 🙂 In your case you may not want these things. The active meshes are the rendered meshes. They evolved constantly based on several options (instances, transparency, etc…)

To keep them as precise as possible costs us a lot per frame,hence why having this freezeActiveMeshes is a good option. THis way you are the driver: you decide which mesh is active and the list remains constant. You can force a mesh to be active by setting `mesh.alwaysSelectAsActiveMesh = true` and you can force it to be inactive with `mesh.setEnabled(false)` for instance

---

<div class="post-metadata">

**Author:** ![jjv360](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jjv360/32/20742_2.png) [@jjv360](https://forum.babylonjs.com/u/jjv360)\
**Post date:** [April 21, 2022, 7:24pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/11 "2022-04-21T19:24:04Z")

</div>

Ok I see, thanks…

---

<div class="post-metadata">

**Author:** ![jjv360](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/jjv360/32/20742_2.png) [@jjv360](https://forum.babylonjs.com/u/jjv360)\
**Post date:** [April 25, 2022, 12:41pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/12 "2022-04-25T12:41:20Z")

</div>

Hi @Deltakosh, I’ve tried to call `unfreezeActiveMeshes();freezeActiveMeshes()` every 1 second as a test and it really helps to reduce the CPU usage a lot, like to around ~50% usage. I do see the culling issue, but that’ll be fixed once your PR is on npm I guess…

My question is, is there anything bad about doing this? One issue I have noticed is that it seems to break animated models, is there a way for animations to continue working while it’s frozen? And is there anything else that would be an issue?

---

<div class="post-metadata">

**Author:** ![Evgeni\_Popov](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/evgeni_popov/32/4432_2.png) [@Evgeni\_Popov](https://forum.babylonjs.com/u/Evgeni_Popov)\
**Post date:** [April 25, 2022, 1:58pm UTC](https://forum.babylonjs.com/t/optimizing-the-render-call/29582/13 "2022-04-25T13:58:44Z")

</div>

I think you can simply call `mesh.skeleton.prepare()` each frame to have your animations going on even when the mesh is frozen.
