i made a website to play music, it uses a lot of animations when you press notes or playback a song. I'm having issues with performance, especially on mobile so i wanted to figure out what was causing it. I went through profiling using google chrome and it's telling me there is a lot of Recalculate Style
happening, and that 30ish elements are affected each time. I've tried making the animations as performant as i could, i use transform scale and background-color animations, plus i added the will-change
prop to the element that has the most changes, in hope to solve issues, but i haven't been able to gain much.
I was thinking that maybe the biggest issue might be with animating background-color as that will cause a repaint throughout the animation, but i still dont understand why it would cause a Recalculate Style
?
CodePudding user response:
Looking at the website, and the discussions in comments. It looks like most your performance issue is due to SVG compositing each time the note changes. SVG rendering in browsers these days is pretty fast, but still not as fast as say a PNG render.
Two options came to mind,.
Create all the notes with the styles set, and then set the visibility. Only issue here is, I'm not sure if the browser will still do a re-render of the SVG when it comes in / out of visibility. Maybe a very Low Opacity could also help here instead. Basically have all the notes states with position absolute on top of each other, the active state would have full opacity, the others a very low one.
Dynamically create the SVG's into PNG's for each state, you could then just flip the PNG's, which should be way faster than the SVG doing a re-draw each time.
Personally I like option 1., but will just need to do some tests. Doing Opacity transitions is certainly fast & smooth in the browser, so you would expect the SVG shouldn't require re-render. I say very low opacity, just in case the browser sees an opacity as 0, as been equivalent to visibility hidden, and decided to loose the render canvas and do another SVG draw when it becomes visible again. Again, some testing here would confirm.