Aller au contenu
useffect.sh
Planifier 30 min avec un senior
Performance

Worklet

Une petite fonction JavaScript que le plugin Babel de Reanimated extrait pour l’exécuter sur le thread UI, dans un runtime séparé.

Définition

Un worklet est une fonction JavaScript courte qui peut s’exécuter sur le thread UI de React Native, dans un runtime JavaScript distinct de celui de l’app, au lieu du thread JavaScript principal. C’est le mécanisme sur lequel reposent Reanimated et Gesture Handler : le callback d’une animation ou d’un geste est copié avec les variables qu’il capture dans ce runtime secondaire, et appelé à chaque frame sans traverser le thread JS. Une fonction devient un worklet par la directive "worklet" en tête de corps, ou automatiquement quand elle est passée à une API de Reanimated, grâce au plugin Babel fourni par react-native-worklets, le package qui porte cette fonctionnalité depuis Reanimated 4. Le worklet remplace l’ancien modèle où chaque frame d’animation exigeait un aller-retour avec le thread JS, source de saccades dès que React travaillait. Vous le rencontrez en écrivant un useAnimatedStyle, en lisant un message d’erreur de Reanimated, ou quand un console.log dans un callback de geste ne fait pas ce que vous attendiez.

Dans une vraie app

La règle à retenir : un worklet ne voit que ce qu’il capture au moment de sa création, et ne peut appeler que d’autres worklets ou des fonctions natives exposées au runtime UI. Appeler une fonction ordinaire (un setState, une navigation, un appel réseau) depuis un worklet lève une erreur ; il faut passer par scheduleOnRN(fn, ...args) de react-native-worklets, qui planifie l’appel sur le thread JS (l’ancien runOnJS de Reanimated 3). Dans l’autre sens, scheduleOnUI remplace runOnUI pour exécuter un worklet depuis le thread JS.

Les pièges typiques : une closure qui capture un gros objet (toute la liste de données, par exemple), recopié dans le runtime UI à chaque création ; une fonction utilitaire importée d’un fichier sans directive worklet et qui échoue au premier appel ; des console.log qui semblent arriver dans le désordre parce qu’ils viennent de deux runtimes. Le message « Tried to synchronously call a non-worklet function on the UI thread » désigne exactement cette situation.

Pour vérifier que le plugin est bien actif, un useAnimatedStyle qui fonctionne suffit ; s’il échoue avec une erreur de worklet, c’est en général babel.config.js (plugin absent ou mal placé) ou un cache Metro à vider. Les worklets peuvent aussi servir hors animation, par exemple pour traiter des frames caméra avec VisionCamera, qui expose son propre runtime de worklets.

Sources

Les 35 termes du glossaire

Un de ces sujets bloque votre app ?

30 minutes avec un senior pour regarder le problème dans votre code. Gratuit.