react-native-reanimated icon indicating copy to clipboard operation
react-native-reanimated copied to clipboard

Add option to autoworkletize function on user request

Open tjzel opened this issue 1 year ago • 2 comments

Summary

This is a feature that will allow the user to workletize specific functions requested by the user, without the need to add worklet directive in them. It's done through new Babel plugin option - autoworkletizationRequests. This property is an object of the following structure:

{
  nameOfTheFileWithFunctionsToWorkletize1: [
    'functionToWorkletizeInThatFile1',
    'functionToWorkletizeInThatFile2',
    'functionToWorkletizeInThatFile3',
  ],
  nameOfAnotherFileWithFunctionsToWorkletize2: [
    'anotherFunction',
  ],
}

Listed functions in given files will become autoworkletized.

Example usage

For a file:

// file.js
function autoworkletizeMe() {
  'worklet';
  console.log('Thank you for autoworkletizing me!');
}

Add this to your babel.config.js:

plugins: [
      'react-native-reanimated/plugin',
      {
        autoworkletizationRequests: {
          file: ['autoworkletizeMe'],
        },
      },
    ]

Notes

What will get autoworkletized

Currently only function declarations will get autoworkletized, namely:

function foo(){}; // OK
const foo = function foo(){}; // OK
const foo = function (){}; // NOT OK
const foo = () => {}; // NOT OK
const obj = {
  foo(){}; // NOT OK
}

This will probably change in the future to support more cases, but as a PoC I stay with function declarations only.

How to make requests

At the moment try to use the longer possible path for the filename, e.g. if you have a file

src/something/else/other/file.js

use as much of the path as possible (keeping in mind building your dist files etc.) so you don't accidentally workletize functions with the same names in the same files. Excess autoworkletization is not harmful to your code, but might unnecessarily inflate its size in the bundle.

Test plan

Perform the steps in Example usage, follow with yarn babel file.js --compact=false -o file.out.js and see in the output file that it got autoworkletized.

Relevant unit tests for plugin will be added later on.

If you want to help test this solution in your project, you can install Reanimated from this tarball react-native-reanimated-3.7.0-20240215104724.tgz with (e.g.) yarn add ./react-native-reanimated-3.7.0-20240215104724.tgz

tjzel avatar Feb 15 '24 10:02 tjzel

Hey that's great 👏 Will it also work with package.json dependencies? What would be the syntax?

xseignard avatar Feb 15 '24 11:02 xseignard

@xseignard Since atm it's roughly a concept, you'd need to specify it accordingly to what do you want to workletize in your babel.config.js for the dependency. It's not really a scalable solution, more of QoL if you want to integrate with Reanimated, just have a few functions that need to be workletized and don't want to change the source code for that.

I'll consider dropping the filename here as @tomekzaw suggested, so then it would be a bit less burdensome.

On the other hand, we are thinking about a solution that would automatically workletize dependencies ran on the UI thread, but it's a looong way till we implement it, provided we actually find a good solution for it.

tjzel avatar Feb 15 '24 12:02 tjzel