How to process nodes asynchronously in batches

I’m planning to search an entire Figma file for layers that use a given style and list them out in my plugin UI. Since this operation is potentially time-consuming (for files that has thousands or even millions of layers), I would like to update my plugin ui in batches of data while the search is happening concurrently

eg Suppose I want to find all layers that have a style of id s:145y5687… and list them down in my plugin UI. Let’s say that there are over 10,000 layers in a user’s figma file so figma.root.findAll(…) will take over an hour to completely synchronously. I want to wait to collect first 50 results from figma.root.findAll(…), process them while figma.root.findAll(…) is running concurrently, then wait until another 50 new results are received.

So here’s my question:

  1. Is it possible to run figma.root.findAll(…) asynchronously?
  2. if 1 is possible, how do I process the returned results in batches?

I’m new to asynchronous functions and promises so any help is appreciated!

1 Like

I’m want to search for text styles, colour styles, and components in the background while my UI is displaying a loading screen. AFAIK, the main ways of extracting these elements are single function calls such as figma.getLocalTextStyles() and figma.root.findAll(). Is there a way to “break up” these calls into smaller chunks?

If you make a spinner or something using CSS only (no JS), it will keep on spinning while the task is processing.

There is no way to break up findAll into chunks other than to launch it on different nodes separately. E.g. you can find all frames on each page of the file first and then launch findAll on every frame, pausing the process for a bit after every findAll is complete.

I’m already using pure css for my loading screen

Unfortunately, parts of it still freezes up when I make the expensive function calls:

As for finding all frames on each page, how do I handle the scenario where component nodes are not put inside frames?

Wait for the UI to load and then call the function.

Also, in the example code that you showed in an older post,

You used a Promise to delay your async function processChunks() for every 100 iterations. Does this mean that delay() takes processChunks() off the main JS thread and allow other functions in code.ts (and even ui.html) to execute, then processChunks() takes over again when the delay “expires”?

Wait for the UI to load and then call the function.
Is there a way for me to detect when ui.html has finished loading? I’ve tried 1. checking the Run event with Figma.on:

2. and I’ve also tried to chain it with as async functions:

Method 2 straight up doesn’t work, and method 1 works partially ie plugin UI window appears, but as a blank window until function is complete

Have you tried using findAllWithCriteria?

I was using findAllWithCriteria and it still took a long time (~30sec) with my design system file which has >1000 components and >10k layers. I’m thinking of trying @Gleb’s approach of calling findAllWithCriteria on each frame in each page, but I’ll also need to handle the case for component nodes which are not a part of any frame

From the UI, send a message to the code when the load event fires.