ClassyKit / Classy

Expressive, flexible, and powerful stylesheets for UIView and friends.
http://classykit.github.io/Classy/
MIT License
740 stars 76 forks source link

UIPageViewController with UICollectionView performance #49

Open morten-holm opened 10 years ago

morten-holm commented 10 years ago

Hi

We are using Classy on a project that has a UIPageViewController where each page has a UICollectionView.

When paging through the pages in the UIPageViewController we notice a small delay and with an attached profiler we notice that some of the time is spent in Classy.

classy_profile

Any advice on a workaround to remove the delay would be great.

cloudkite commented 10 years ago

Are you using the latest version of classy?

morten-holm commented 10 years ago

Just tried it with 0.2.4 and with 'head' version of the Pod. I'm seeing the same thing in the profiler.

cloudkite commented 10 years ago

If you send me a simplified example project happy to look into it, thanks.

morten-holm commented 10 years ago

I have created a demonstration project:

https://github.com/morten-holm/ClassyPageViewController.git

cloudkite commented 10 years ago

@morten-holm sorry have been very busy with work, will have a look soon. Thanks for posting a demo project!

cloudkite commented 10 years ago

@morten-holm I don't think the demo project has the small delay? Whatever was causing the delay must be missing from the new project. Maybe try adding in code/styles until you get same delay so we can pinpoint the issue.

This is what I got when profiling your demo

screen shot 2014-03-20 at 7 30 48 am

morten-holm commented 10 years ago

Have you tried running it on a device? I used an iPad 3 and can verify that i saw the delay when slow dragging to expose the next viewcontroller.

cloudkite commented 10 years ago

@morten-holm Sorry for the delayed response! I just ran on iphone 4S and didn't notice slow down. Have you tried updating to latest head? this commit https://github.com/cloudkite/Classy/commit/d333fa7f0ee6f1fad7ea26630594fa88fee03b5e should improve performance.

morten-holm commented 10 years ago

Hi Jonas

It's been a while, but i finally got around to updating the example to further demonstrate the delay when changing view controllers.

I suspect that the problems we are seeing are due to a quite complex view hierarchy and a 'larger' stylesheet.

The example app is exaggerated compared to our real app but demonstrates the problem very clearly.

cloudkite commented 10 years ago

No problem, will have another look when I get time later this week, thanks!

cloudkite commented 10 years ago

Sorry for the delay, will have a look this weekend

cloudkite commented 10 years ago

@morten-holm have done some profiling and have identified a couple of bottlenecks in the code, however optimising it will take some digging and time which I am a bit short on at the moment. If you have any ideas or would like to help there are the main culprits.

1) This is probably the main one, the current code loops through each styleSelector and checking if there is a match. This will be especially slow if you have a large stylesheet and/or lots of views https://github.com/cloudkite/Classy/blob/master/Classy/Parser/CASStyler.m#L60-L68

2) Classy tries to aggregate calls to styling, this is to avoid doubling up on styling if you set cas_styleClass multiple times within the same runloop ie

- (void)someMethod {
    self.someView.cas_styleClass = "first";
    ....
    self.someView.cas_styleClass = "again";
}

Will only result in one call to styling. However this is currently implemented in a very inefficient way and could be cleaned up alot or removed if that helps performance https://github.com/cloudkite/Classy/blob/master/Classy/Parser/CASStyler.m#L621-L649

3) NSHashTable is slow according to http://www.objc.io/issue-7/collections.html https://github.com/cloudkite/Classy/blob/master/Classy/Parser/CASStyler.m#L48

daniel-hightail commented 9 years ago

Running into an issue on collection views in page view controllers on my own and saw this so I'll give some 2 cents. You can try to use AAPLAdvancedCollectionView (I believe the iTunes/Store app uses this) and dispatch some of the parse work for loading the collection view datasource on a background thread and to not let the datasource set any items until that work is finished. It should make the initial load smoother which will allow the gesture to run without interruption on the current run loop and then when the delegate of the page view controller calls back that the page did change you can let the collection load its items from the completed parse work.