CALayer compositing/animations become extremely slow over time

This applies to macOS 10.13.3 beta 5 (and previous 10.13)


I have a macOS app that heavily uses custom CALayer-hosting views. When my application is freshly started everything is as expected, the UI is responsive and quick. However, after several heavy-duty "operations" involving destroying and creating of many overlapping layers as well as repainting them, my app's UI becomes almost completely unresponsive.


Simply put all UI updates like layer updates or fade-in/out animations (which is the only type of animation in use), get extremely slow. A layer fade in that normally takes a fraction of a second suddenly takes 4 seconds.


The unresponsiveness also extends to the main menu item highlighting, which becomes extremely sluggish.


I've debugged this for 3 days and can say that it isn't caused by a leak on my part (one that the Instruments would detect anyway). I can easily recreate this any time on my development machine (MacBook Pro 2016, 16GB Ram, 4k external display). The same app using the same (automated) test cycle works fine on a different MacBook Pro 2012 (8GB Ram, no external display) running macOS 10.12. My machine needs 80 test cycles to get to the state of UI freeze, the 10.12 machine can run the test indefinitely without performance impact.


Anyone else here experiencing the same problem? I'm open to the idea that this is a problem caused by me doing something that I shouldn't, but I have no clue where to look.


Regards

M

Answered by Hunter in 290128022

Is it possible that you're not actually removing these layers when you think that you are?


You should be able to detect something like that in Instruments - counts of CALayer objects, if the app's memory usage keeps increasing, etc... Those wouldn't always be caught by the leaks instrument depending on the specifics.


Is your app using a ton of CPU when this happens?

Accepted Answer

Is it possible that you're not actually removing these layers when you think that you are?


You should be able to detect something like that in Instruments - counts of CALayer objects, if the app's memory usage keeps increasing, etc... Those wouldn't always be caught by the leaks instrument depending on the specifics.


Is your app using a ton of CPU when this happens?

Thanks for making me look again!! It turned out that the number of CALayers kept increasing.


The reason seems to be a change in behavior in 10.13 in that a layer's delegate is cleared automatically when the delegate is being destroyed (actually sometime before -dealloc is called). That makes testing against the layer's delegate value useless inside of -dealloc in my case where layer owner and delegate are the same object. Since that test failed, it resulted in the layer not being removed from the superlayer (though it was properly released by the owner).


Thanks again!


Regards

M

CALayer compositing/animations become extremely slow over time
 
 
Q