# EffectComposer performance

**URL:** <https://discourse.threejs.org/t/effectcomposer-performance/57651>\
**Category:** Questions\
**Tags:** post-processing, performance\
**Created:** [November 1, 2023, 7:26pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651 "2023-11-01T19:26:45Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![new](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/new/32/25580_2.png) [@new](https://discourse.threejs.org/u/new)\
**Post date:** [November 1, 2023, 7:26pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/1 "2023-11-01T19:26:45Z")

</div>

In my app I use React with vanilla ThreeJS (yes, no `react-three-fiber`, please don’t advise it). There I have a function that creates EffectComposer:

```javascript
const bufferSize = new Vector2();
export const createComposer = (renderer: WebGLRenderer) => {
  let renderTarget = undefined;
  const size = renderer.getDrawingBufferSize(bufferSize);
  renderTarget = new WebGLRenderTarget(size.width, size.height, {
    samples: 8,
  });
  return {composer: new EffectComposer(renderer, renderTarget), target: renderTarget};
};

```

I use the created composer in another component and handle resize there if needed (for that reason I return target here).

Everything works, but what bothers me is if I create composer on every re-render it yields better frame rate than if I memorize it:

```javascript
const { composer, target } = useMemo(() => createComposer(renderer), []); // Slow!
const { composer } = createComposer(renderer); // Fast. Also no need to handle resize since it is recreated.

```

When composer is re-created on every re-render I call `dispose()` for it.  
So, my question is why it behaves like this? How can I optimize the memory allocation and performance at the same time?

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [November 1, 2023, 7:56pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/2 "2023-11-01T19:56:23Z")

</div>

> [@new](#):
>
> if I create composer on every re-render

What does re-render mean? I suppose you don’t have an animation loop and render on demand, right?

It would be strange if the disposal and re-creation would yield a better performance. That should definitely be investigated. Are you able to demonstrate the issue with a live example?

---

<div class="post-metadata">

**Author:** ![new](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/new/32/25580_2.png) [@new](https://discourse.threejs.org/u/new)\
**Post date:** [November 1, 2023, 8:12pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/3 "2023-11-01T20:12:56Z")

</div>

By re-render I mean re-render of the react component. Also, I do have animation loop. If to simplify, I have the following:

```javascript
export type BaseSceneObjects = {
  scene: THREE.Scene;
  renderer: WebGLRenderer;
  camera: PerspectiveCamera;
  renderingObject: Object3D;
  renderingObjects: Object3D[];
  viewerTexture?: Texture;
};

export function Viewer(baseScene: BaseSceneObjects) {
    const { composer, target } =
    // useMemo(() => createComposer(baseScene.renderer), []); // Executed only once when comonent is created. Slow!
    createComposer(baseScene.renderer); // Executed whenever React re-renders the component. Fast :/

    updateSize(camera, renderer, composer, target, width, height);

    const postPasses = useMemo(() => initPostprocessingPasses(scene, camera), []); // Calls function to create post-processing passes once and memorizes the value.

    useCallback(
      (composer: EffectComposer, postPasses: PostProcessingPasses) =>
        initPostprocessing(composer, postPasses),
      []
    )(composer, postPasses);

    const stats = useMemo(() => new FpsStats(), []);
    renderer.setAnimationLoop(() => {
      TWEEN.update();
      controls.autoRotate();
      stats.begin();
      composer.render();
      if (!isMobile) {
        handleFps(stats, postPasses);
      }
    });

    useEffect(() => {
     // Some code here
      return () => {
        controls.dispose();
        composer.dispose();
      };
    }, []);

    return (<div>....</div>)
}

const initPostprocessingPasses = (
  scene: Scene,
  camera: PerspectiveCamera
): PostProcessingPasses => {
  return {
    taaPass: new TAARenderPass(scene, camera),
    outputPass: new OutputPass(),
    renderPass: new RenderPass(scene, camera),
  };
};

const initPostprocessing = (
  composer: EffectComposer,
  postprocessingPasses: PostProcessingPasses
) => {
  //... Some code here
  composer.addPass(postprocessingPasses.renderPass);
  composer.addPass(postprocessingPasses.taaPass);
  composer.addPass(postprocessingPasses.outputPass);
};

const updateSize = (
  camera: PerspectiveCamera,
  renderer: WebGLRenderer,
  composer: EffectComposer,
  target: WebGLRenderTarget,
  width: number,
  height: number
) => {
  camera.aspect = width / height;
  camera.updateProjectionMatrix();
  renderer.setSize(width, height);
  target.dispose();
  target.setSize(width, height);
  composer.setSize(width, height);
};

```

I will try to demonstrate it in the fiddle, please let me some time.

---

<div class="post-metadata">

**Author:** ![new](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/new/32/25580_2.png) [@new](https://discourse.threejs.org/u/new)\
**Post date:** [November 7, 2023, 9:41pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/4 "2023-11-07T21:41:11Z")

</div>

Hi @Mugen87 ,

Please find the promised code here: [GitHub - SSopin/ComposerTest: Test code for ThreeJS composer paired with React.](https://github.com/SSopin/ComposerTest)

Most likely I am doing something wrong, but it is suspicious.

---

<div class="post-metadata">

**Author:** ![new](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/new/32/25580_2.png) [@new](https://discourse.threejs.org/u/new)\
**Post date:** [November 10, 2023, 3:27pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/5 "2023-11-10T15:27:51Z")

</div>

Hi @Mugen87,

Could you please suggest if you had a chance to check the code? I am curious to hear your verdict 🙂

---

<div class="post-metadata">

**Author:** ![Lawrence3DPK](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/lawrence3dpk/32/29184_2.png) [@Lawrence3DPK](https://discourse.threejs.org/u/Lawrence3DPK)\
**Post date:** [November 10, 2023, 4:35pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/6 "2023-11-10T16:35:31Z")

</div>

You’re probably best off creating a codesandbox from the repo as a live demonstration of the issue, it would be much easier to access and debug than having to download and install your entire project…

---

<div class="post-metadata">

**Author:** ![new](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/new/32/25580_2.png) [@new](https://discourse.threejs.org/u/new)\
**Post date:** [November 10, 2023, 4:53pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/7 "2023-11-10T16:53:23Z")

</div>

Thanks @Lawrence3DPK . Here it is [the link](https://codesandbox.io/p/github/SSopin/ComposerTest/main?layout=%257B%2522sidebarPanel%2522%253A%2522GIT%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522closum13h00073b6i5ipm2coz%2522%252C%2522sizes%2522%253A%255B73.72148859543817%252C26.278511404561826%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522closum13h00033b6ix7mm81ki%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522closum13h00053b6iabd1obwv%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522closum13h00063b6iil2qm8ab%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B60%252C40%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522closum13h00033b6ix7mm81ki%2522%253A%257B%2522id%2522%253A%2522closum13h00033b6ix7mm81ki%2522%252C%2522activeTabId%2522%253A%2522closurvk3004y3b6i431zp50u%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522closum13h00023b6i0dl3ot4n%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252FREADME.md%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%252C%257B%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252Fsrc%252FComposerTest.tsx%2522%252C%2522id%2522%253A%2522closurvk3004y3b6i431zp50u%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%257D%252C%2522closum13h00063b6iil2qm8ab%2522%253A%257B%2522id%2522%253A%2522closum13h00063b6iil2qm8ab%2522%252C%2522activeTabId%2522%253A%2522closur65h00vt3b6i6zme5zok%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522TASK_PORT%2522%252C%2522taskId%2522%253A%2522start%2522%252C%2522port%2522%253A3000%252C%2522id%2522%253A%2522closur65h00vt3b6i6zme5zok%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522path%2522%253A%2522%252F%2522%257D%255D%257D%252C%2522closum13h00053b6iabd1obwv%2522%253A%257B%2522id%2522%253A%2522closum13h00053b6iabd1obwv%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522closum13h00043b6ikeyq9waa%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522TERMINAL%2522%252C%2522shellId%2522%253A%2522closum18n000iedf0fxgq7v00%2522%257D%252C%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522start%2522%252C%2522id%2522%253A%2522closum1id005u3b6iuv904ba7%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%252C%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522CSB_RUN_OUTSIDE_CONTAINER%253D1%2520devcontainer%2520templates%2520apply%2520--template-id%2520%255C%2522ghcr.io%252Fdevcontainers%252Ftemplates%252Ftypescript-node%255C%2522%2520--template-args%2520%27%257B%257D%27%2520--features%2520%27%255B%255D%27%2522%252C%2522id%2522%253A%2522closumyr100dv3b6ipqwwpcza%2522%252C%2522mode%2522%253A%2522permanent%2522%257D%255D%252C%2522activeTabId%2522%253A%2522closum1id005u3b6iuv904ba7%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D). Please let me know if it works, I am new to codesandbox 🙂

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [November 11, 2023, 10:57am UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/8 "2023-11-11T10:57:20Z")

</div>

There seems to be an issue with the reproduction test case. The default code runs and outputs the average FPS on the screen. But when I switch to the other setting, meaning:

```js
  //const composerAndTarget = createComposer(renderer); // Fast
  useMemo(() => createComposer(renderer), []); // Slow

```

I get a runtime error:

> Cannot find name ‘composerAndTarget’.

---

<div class="post-metadata">

**Author:** ![new](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/new/32/25580_2.png) [@new](https://discourse.threejs.org/u/new)\
**Post date:** [November 13, 2023, 9:22pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/9 "2023-11-13T21:22:43Z")

</div>

Hi @Mugen87 ,

Sorry for the confusion. Another mode should look following:

```javascript
const composerAndTarget = useMemo(() => createComposer(renderer), []); // Slow

```

I updated the code, please check again once you can. Thanks.

---

<div class="post-metadata">

**Author:** ![new](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/new/32/25580_2.png) [@new](https://discourse.threejs.org/u/new)\
**Post date:** [November 16, 2023, 4:06am UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/10 "2023-11-16T04:06:38Z")

</div>

Hi @Mugen87,

Could you please suggest if the code I provided works now? We just shouldn’t have commented this part: `const composerAndTarget = `, but I duplicated it there, so now you can comment the full line.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [November 16, 2023, 9:54am UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/11 "2023-11-16T09:54:03Z")

</div>

Strange, I can’t update the codesandbox anymore. It requires a sign in now which wasn’t necessary last time. Did something change in the sandbox configuration?

---

<div class="post-metadata">

**Author:** ![new](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/new/32/25580_2.png) [@new](https://discourse.threejs.org/u/new)\
**Post date:** [November 16, 2023, 6:22pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/12 "2023-11-16T18:22:40Z")

</div>

Not really, I didn’t update the configs. Just one line of code.  
However, it seems you need to be logged in and I need to share it with you personally using the your username or email to be able to edit, otherwise it is read-only. Is there any other way I can share it?

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [November 17, 2023, 10:22am UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/13 "2023-11-17T10:22:28Z")

</div>

Since I don’t want to log in, I have just downloaded your code and tried to debug it locally. I can reproduce the drop in performance but I’m unable to find a reason for this in the `three.js` code base. There must be a react related root cause. However, I’m not familiar enough with react to further investigate the issue.

If you believe the issue comes from the `three.js` side, it would be best to share a reproduction test case with plain `three.js` (meaning without react or any other dependencies).

---

<div class="post-metadata">

**Author:** ![new](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/new/32/25580_2.png) [@new](https://discourse.threejs.org/u/new)\
**Post date:** [November 17, 2023, 3:41pm UTC](https://discourse.threejs.org/t/effectcomposer-performance/57651/14 "2023-11-17T15:41:53Z")

</div>

Got it. Thanks a lot! I will try to investigate the issue and let you know if I find something related to `three.js` there.
