# Blendshape Animation for Visemes slow

**URL:** <https://discourse.threejs.org/t/blendshape-animation-for-visemes-slow/61681>\
**Category:** Questions\
**Tags:** blendshapes, react-three-fiber, animation\
**Created:** [February 20, 2024, 10:45am UTC](https://discourse.threejs.org/t/blendshape-animation-for-visemes-slow/61681 "2024-02-20T10:45:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![CHOIX](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/choix/32/294_2.png) [@CHOIX](https://discourse.threejs.org/u/CHOIX)\
**Post date:** [February 20, 2024, 10:45am UTC](https://discourse.threejs.org/t/blendshape-animation-for-visemes-slow/61681/1 "2024-02-20T10:45:42Z")

</div>

I get the `BlendShapes`, which contains an array of 55 facial positions represented as decimal values between 0 to 1 from Microsofts speech API and apply them in the useFrame loop in my react three fiber project.

```javascript
{
    "FrameIndex":0,
    "BlendShapes":[
        [0.021,0.321,...,0.258],
        [0.045,0.234,...,0.288],
        ...
    ]
}

```

```javascript
    synthesizer.visemeReceived = function (s, e) {
        const visemeId = e.privVisemeId;
        const timestamp = e.privAudioOffset / 10000; // Convert to milliseconds
        setVisemeIDs(prevVisemeIDs => [...prevVisemeIDs, { id: visemeId, timestamp }]);
        const parsedAnimation = JSON.parse(e.animation); // Expected to be of type ParsedAnimation
        setFrameQueue((prevQueue) => [...prevQueue, ...parsedAnimation.BlendShapes]);
    };

    const [frameQueue, setFrameQueue] = useState([]);
    
    useFrame(() => {
        if (frameQueue.length > 0) {
            const currentFrame = frameQueue[0];
            nodes.mesh.morphTargetInfluences = currentFrame;
            setFrameQueue(prevQueue => prevQueue.slice(1));
        }
    });

```

On Desktop and Mobile it works smooth (an offset of audio and viseme animation is there, since I couldn’t make use of the privAudioOffset… not focus of this question) - but on meta Quest2 it is very very laggy (hello motion sickness!) I guess the way I am getting the Blendshapes and pre-saving them in a temporary array to use it later in the useFrame is causing a lot of problems; since this example here works very smooth on the Quest2: [three.js webgl - morph targets - face](https://threejs.org/examples/webgl_morphtargets_face)

Any ideas how I could optimize my code?

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [February 20, 2024, 2:43pm UTC](https://discourse.threejs.org/t/blendshape-animation-for-visemes-slow/61681/2 "2024-02-20T14:43:12Z")

</div>

Using stateful hooks like `useState()` will cause the React component to re-render. It’s very important that React components _not_ re-render on every frame, so calling state setters inside of `useFrame` or other continuously-running callbacks must be avoided when using React. See:

[https://docs.pmnd.rs/react-three-fiber/advanced/pitfalls#avoid-setstate-in-loops](https://docs.pmnd.rs/react-three-fiber/advanced/pitfalls#avoid-setstate-in-loops)

---

<div class="post-metadata">

**Author:** ![fangliangv587](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/fangliangv587/32/47675_2.png) [@fangliangv587](https://discourse.threejs.org/u/fangliangv587)\
**Post date:** [May 10, 2024, 2:44am UTC](https://discourse.threejs.org/t/blendshape-animation-for-visemes-slow/61681/3 "2024-05-10T02:44:30Z")

</div>

I also focus this，can you share your complete project source code to reference
