# Optimize performance of ShadowGenerator.Parse

**URL:** <https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086>\
**Category:** Completed Features\
**Tags:** sceneserializer, performance, serialization, shadowgenerator\
**Created:** [August 15, 2025, 8:28am UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086 "2025-08-15T08:28:50Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![kzhsw](https://avatars.discourse-cdn.com/v4/letter/k/848f3c/32.png) [@kzhsw](https://forum.babylonjs.com/u/kzhsw)\
**Post date:** [August 15, 2025, 8:28am UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086/1 "2025-08-15T08:28:50Z")

</div>

## Background

`ShadowGenerator.Parse` called `scene.getMeshesById`, which is O(n) in time, for each mesh id in `parsedShadowGenerator.renderList`, makes the loop O(m\*n) in time, where n is the count of meshes in scene, m is the count of items in renderList.

> <https://github.com/BabylonJS/Babylon.js/blob/33e16b7a18dc6b2cfc1d9161628de55b1f60a45b/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts#L2159>

And profiler shows there is a perf bottleneck in call to `getMeshesById`

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/5/6/56be7d96708cbef99771a16944d8ad95072190b3.png)

## Proposal

Use a set of id for efficient matching, should be O(m) in space, and O(n) in time.

```patch
diff --git a/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts b/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts
index 34eb5b4c65..7ad0124070 100644
--- a/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts
+++ b/packages/dev/core/src/Lights/Shadows/shadowGenerator.ts
@@ -2155,16 +2155,17 @@ export class ShadowGenerator implements IShadowGenerator {
         const shadowGenerator = constr ? constr(parsedShadowGenerator.mapSize, light, camera) : new ShadowGenerator(parsedShadowGenerator.mapSize, light, undefined, camera);
         const shadowMap = shadowGenerator.getShadowMap();
 
- for (let meshIndex = 0; meshIndex < parsedShadowGenerator.renderList.length; meshIndex++) {
- const meshes = scene.getMeshesById(parsedShadowGenerator.renderList[meshIndex]);
+ if (parsedShadowGenerator.renderList.length && shadowMap) {
+ const renderSet = new Set<string>(parsedShadowGenerator.renderList);
+ let renderList = shadowMap.renderList;
+ if (!renderList) {
+ renderList = shadowMap.renderList = [];
+ }
+ const meshes = scene.meshes;
             for (const mesh of meshes) {
- if (!shadowMap) {
- continue;
- }
- if (!shadowMap.renderList) {
- shadowMap.renderList = [];
+ if (renderSet.has(mesh.id)) {
+ renderList.push(mesh);
                 }
- shadowMap.renderList.push(mesh);
             }
         }

```

---

<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:** [August 15, 2025, 4:28pm UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086/2 "2025-08-15T16:28:39Z")

</div>

I’m game!

Thanks a lot btw for all these tidbits of optimization! This is great

---

<div class="post-metadata">

**Author:** ![kzhsw](https://avatars.discourse-cdn.com/v4/letter/k/848f3c/32.png) [@kzhsw](https://forum.babylonjs.com/u/kzhsw)\
**Post date:** [August 16, 2025, 12:41am UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086/3 "2025-08-16T00:41:53Z")

</div>

And a PR here:

> <https://github.com/BabylonJS/Babylon.js/pull/17034>
>
> The \`ShadowGenerator.Parse\` method exhibited a performance bottleneck due to its… inefficient handling of the \`renderList\`. Previously, it iterated through the \`parsedShadowGenerator.renderList\` and for each mesh ID, it called \`scene.getMeshesById\`. This resulted in an O(m\*n) time complexity, where 'n' is the total number of meshes in the scene and 'm' is the number of meshes in the \`renderList\`. Profiling indicated that \`getMeshesById\` was a significant performance drain.
> 
> This commit refactors the parsing logic to improve efficiency. Instead of repeatedly querying meshes by ID, it now creates a \`Set\` of mesh IDs from the \`renderList\` (O(m) time and space). It then iterates through all meshes in the scene once (O(n) time) and checks for membership in the \`Set\` using an O(1) average time complexity lookup. Any mesh whose ID is found in the set is added to the \`shadowMap.renderList\`.
> 
> This change reduces the overall time complexity of parsing the \`renderList\` to O(n + m), which is a substantial performance improvement, especially for scenes with a large number of meshes or a large \`renderList\`.
> 
> Forum post: \<https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086\>

And seems something wrong with CI, without detailed error again

> **[Pipelines](https://dev.azure.com/babylonjs/ContinousIntegration/_build/results?buildId=43035&view=logs&jobId=e7b80b24-15e8-561b-2b9b-3069817c0357&j=e7b80b24-15e8-561b-2b9b-3069817c0357&t=d44cc3c9-51e1-5b48-81c7-6e896dd5dc67)**

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [August 18, 2025, 2:54pm UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086/4 "2025-08-18T14:54:35Z")

</div>

@ryantrem and @AlitarSemiramis can you check if we could display the error somehow ?

---

<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:** [August 18, 2025, 3:06pm UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086/5 "2025-08-18T15:06:35Z")

</div>

Can you run `npm run format:fix ?`

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [August 18, 2025, 3:17pm UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086/6 "2025-08-18T15:17:27Z")

</div>

Not sure how but you did the same:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/1/a/1a0c257367e811c7729fb52b30c49fb793f48071.png)

fixed in your PR

---

<div class="post-metadata">

**Author:** ![kzhsw](https://avatars.discourse-cdn.com/v4/letter/k/848f3c/32.png) [@kzhsw](https://forum.babylonjs.com/u/kzhsw)\
**Post date:** [August 25, 2025, 3:38am UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086/7 "2025-08-25T03:38:24Z")

</div>

Oh, never noticed that, my local copy works fine, but after pasting to github “Edit”, it added a new line. Thank you for that.

---

<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:** [August 25, 2025, 3:15pm UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086/8 "2025-08-25T15:15:07Z")

</div>

Thank YOU for your appreciated help!

---

<div class="post-metadata">

**Author:** ![sebavan](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/sebavan/32/57_2.png) [@sebavan](https://forum.babylonjs.com/u/sebavan)\
**Post date:** [August 25, 2025, 3:31pm UTC](https://forum.babylonjs.com/t/optimize-performance-of-shadowgenerator-parse/60086/9 "2025-08-25T15:31:26Z")

</div>

nw I feel like I helped lol
