Multiple canvas performance on mobile safari

I'm using iPad 12.9" M1 Safari and I noticed that having a bunch of canvases seems to slow down the "canvas" element itself. Every other widget is very responsive and quick, but having around 34 canvases in my template I noticed that ALL of the canvases tend to slow down. What I mean by saying slow down is that the touch events seem to be a little bit more delayed than when using a smaller number of canvases in the template. I've tried experimenting with the canvases having no code at all but a simple variable that adjusts a single CSS property on touch start/end and in all cases the more canvases I have the slower they all seem to be? Is this intended or only prune to mobile webkit thing? I can't really test out a different browser on my apple devices as they all still use webkit underneath. What's interesting is that all other widgets that are not canvases are running smooth as butter.
I have 1 canvas that has 31 clones and 2 separate canvases in my template. I tried leaving them all uncoded like I mentioned, but the issue is still there.

Would you mind uploading your test session please ?

I was about to upload a sample session but I quickly noticed the issue!!

It appears that whenever JS in CSS is used it heavily impacts the performance of the widget.. For example using this line:
animation: #{VAR{'isEnabled'} ? 'pulse2 0.8s ease-in-out infinite' : ''};
immediately makes the widget performance slower than usual.

The animation in context:

@keyframes pulse2 {
    0%{opacity: 1}
    50%{opacity: 0.2}
    100%{opacity: 1}
}

I suppose I can rephrase my question here since this is the case -- how could I go about adding an animation to a widget based on a variable without sacrificing the performance?

EDIT: When I start cloning the canvas and make around 30 of them that's when this issue actually becomes noticeable. Using iPad 12.9" M1 18.0 iOS, Safari

JS in CSS can only affect performance if its content is evaluated again, otherwise the browser just sees static css, are you sure the perfmance isn't simply affected by the css animation itself ?

performance.json (53.1 KB)

here's a test session file showing the issue.
Here's what I observed, testing on Safari iPad 12.9" M1 18.0 iOS:

  • Removing the animation CSS property from loopCanvas_0 makes the performance problem disappear
  • Removing svg elements: resampleIcon, moveIcon, copyIcon, extendIcon, divideIcon that also have that CSS property reduces this performance issue
  • Leaving only the faders and loopCanvas in the panel also reduces the impact of this issue quite a lot.
  • Removing some elements that have their value based on a variable also mitigates this performance issue soloLight, replaceLight, overdubLight, playLight
  • For me it's still quite abstract what's exactly causing this issue but as far as I see what they all have in common is basing a value or a css off of an variable..
  • This issue does not happen on Windows/Mac computers, I would dare to say it's only mobile safari related, but I do not have an Android tablet or iOS capabilities of testing with something without a webkit underneath.

Does replacing the VAR{} statements with static values change anything ?

Yeah, if I leave only just
animation: pulse2 0.8s ease-in-out infinite; on the canvas element
the problem immediately goes away and it become very quick and responsive.

I also tried making a canvas that's not cloned to do the same functionality and having the VAR statement in CSS immediately slowed it down. But like I said, it feels like the more canvas elements I have the more noticeable this drop becomes.

EDIT: if I change the VAR name to something that's undefined, not set anywhere, then this problem doesn't happen. i.e. I use isEnabled naming, but if I change the CSS var to
animation: #{VAR{'isEnableds'} ? 'pulse2 0.8s ease-in-out infinite' : ''}; by just adding the 's' at the end of the var name, the problem disappears. It looks like it has something to do with var resolving..

I think I found and fixed the cause of the issue !

Are you referencing this commit?

I seem to get e.options is undefined in my client console.
After adding optional chaining it goes away but the issue regarding the performance seems to still be not addressed with this.

EDIT: Also this feels very similar to the issue I was having here -- Syncing animations to midi clock . It feels as if though whenever JS variables in CSS are being resolved it really takes a toll on the performance in a mobile webkit browser.

I seem to get e.options is undefined in my client console.

Woops, fixed.

As far as I can see that was the only thing happening that scaled with the number of clones. The property resolution is now happening only once when touching the canvas and once when releasing.

Please try the latest commit, I found another potential performance hit related to the css property.

sample.zip (1.7 MB)

hmm it still seems to perform the same. I've attached a small demonstration video for you to get a better idea. The first touch is done when animation: #{VAR{'isEnabled'} ? 'pulse2 0.8s ease-in-out infinite' : ''}; is present on the canvas CSS style, all the other touches after the first one are done while that style with VAR is not present. You can see the there is a noticeable delay when I first touch the canvas, I have enough time to fully raise my finger off of the screen before I see the onTouch script is executed and those faders are adjusted.

Modifying the css of canvas based widgets does trigger some costly checks that are hard to avoid (css may affect the drawing). I'd like to find a way to improve that but for now the best option is maybe to put the css animation rule on the parent container and call setVar('parent', 'isEnabled', state) wherever needed to avoid the issue.

Edit: actually, can you try the latest commit and add /* noresize */in your canvas' css ? This should bypass the most costly checks.