Draw/redraw performance tips?

Hi, if I have say 20 lines of text and I have a script that,

  1. records the style attributes of the text (font size, color…)
  2. creates a new Text component for each line of text and positions them, applying the text attributes as it goes. All functions are async and awaited.
  3. I group this initial set of rendered Text objects.

I find that it’s taking ~ 250-500ms to draw the list. It gets slower with more items. I have a panel that lets you modify some properties like the Text items’ position (spacing), alignment… Each time a setting is changed I redraw the list. I have tried two different re-render strategies:

  • Strategy A: Delete all items in the group then redraw with the same logic as the first time they were drawn, using the updated properties from the UI panel.
  • Strategy B: When drawing the original set of Text items, retain references to their guids. When re-rendering, reposition the existing text objects and update their properties using guids to obtain references to the correct objects.

Both of these strategies had comparable performance and #1 is what I have stuck with because the code is less complex.

So, if I have a button that increases font size and repositions text and I click it three times quickly, it feels very laggy as the renderer takes longer to draw the updated Text objects than it takes to click the button.

Can you think of any tips to improve performance? I’m unclear how relevant using async/await is with the drawing APIs with respect to performance in XD (I do understand async/await well, in general from a JS standpoint).

Thank you!

1 Like

@abcd_ca Note that the scenegraph manipulations in XD are not asynchronous, unlike other unnamed UXP-based point products.

So any awaiting you’re doing may be wasting time, though it should be minimal.

1 Like

While I agree it shouldn’t make too much of a difference, I’m unsure how this works in practice (this may depend on the JS engine?).

When chaining many awaits together in, say, a loop (which is where “it gets slower with more items” would make sense), wouldn’t it have to work on a large callstack for every additional await that has to get executed in sequence.

If you had, say, 500 await statements in sequence in a loop, it is my understanding that this gets intrepreted as basically a callstack that’s 500+ levels deep (with callbacks for each subsequent statement), which could lower the performance…

Just some thoughts, though. I don’t really have the time to test this right now…

What’s likely slowing things down (if it is) is letting XD get in a full UI cycle on every await. That could get expensive.

1 Like

Thanks guys, I will play with it and see if I can improve.

1 Like

So, I was having trouble installing my plugin this morning and realized eventually that I had disabled my development plugin. Once I figured that out I was back in business. During the troubleshooting I updated XD to v30.2.12.3 which I fear may have muddied the problem and testing.

Prior to making changes and after updating I noticed that my plugin now renders at least 4x slower. I can see the panel on the right where you choose font, colour… flickering while it redraws the component. It used to take about 0.5 to 1 second to render and now it takes around 4 seconds.

I removed all async/await from my code except for the async on the function passed to editDocument and I am not seeing any appreciable difference.

Is it possible that the updated version of XD is responsible? I wish I hadn’t updated so I could have had a cleaner test :face_with_monocle:
.

1 Like

Not having any troubles creating dozens or hundreds of scenegraph objects per second, with the latest XD.

Something else must be going on.

1 Like

That’s helpful, thanks. I’ll focus on checking my code.

Definitely something fishy going on – are you sure you have the same version as me? I have tried rolling back my code to a version that definitely worked faster so the only new thing is either the latest XD or something environmental on my computer but not the code.

Could be–I’m running what I think is the latest, Xd 30.0.12.14. Oh, wait, I see I missed the latest. Will check…

[back later]

Hmm, could be a tad slower than previous version, but certainly not 4-5x slower.

Interesting, I just tried the following things:

  1. stayed on an old, rolled back commit which is still slow in v30.2.12.3 (as mentioned before)
  2. using OS X Time Machine, was able to restore XD v28.9.12.2. Same code branch runs as fast as it used to – and more like 100ms to 250ms not 0.5-1s as originally stated. There’s a slightly noticeable lag but it’s probably acceptable (I wish it were instant but I’m OK with it).
  3. rolled forward to the second last commit where I still had async/await on all the render functions. Still fast. Rolled forward to latest version with async/await taken out (all synchronous except for the callback on editDocument). Couldn’t notice a difference, not faster, not slower.
  4. Staying on this latest code branch, switched XD version back to latest v30.2.12.3. Really slow.

Maybe something for @Adobe to comment on.