Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSTableview View Based Scrolling Performance

I am fairly new to OS X Cocoa programming but have decided to give it a go with the new Swift language.

I have an NSTableView with 1500 rows (will be more) and 7 columns. There is one checkbox column and the rest are text fields, one with a date formate and one a currency formatter. I first set this up as cell based. Scrolling was buttery smooth (I even did a test adding 1 million rows, still smooth). This was under mavericks.

I then upgraded to Yosemite, scrolling performance significantly degraded. Enabling Core animation layer checkbox on the table view improved this but was still worse than in mavericks.

During my reading trying to improve scroll performance in Yosemite I came across "View-Based" NSTableViews. From the documentation it said cell based table views should generally not be used and are only supported for legacy projects.

I therefore converted my table to a View based table view. Sample simple concept, nothing complicated. The scrolling performance is absolutely terrible. If you scroll very slow it is smooth enough but as soon as you start to scroll faster its like it hasn't buffered enough and it starts stuttering and jerking. Also when the NSTableview is populated, focusing and defocusing the window takes a second or more (I tried it in mavericks again and this was not present, scrolling was also a little better, but still nowhere near cell based).

Are view based NSTableviews always bad for scrolling performance? If so why do apple recommend using them over cell based NSTableviews.

Also some applications like safari and Reeder2 have buttery smooth scrolling even in Yosemite. How do they achieve this?

Am I missing something or is the performance of OS X just going to hell with each new thing? I.e

Mavericks > Yosemite

Cell-Based > View-Based

Old > New

Any help is much appreciated. Thanks!

like image 839
Gavin Avatar asked Nov 02 '14 06:11

Gavin


2 Answers

According to Apple, OSX never enable QuartzCore by default (as iOS, instead, do). So, you need to:

  • link against QuartzCore.framework your project under Build Settings pane.
  • enable CoreAnimation Layer (under View Effects Inspector on IB) for your main window (if possible, otherwise be sure to enable it on the container view that give you poor performances).

Quoting Apple docs:

In iOS apps, Core Animation is always enabled and every view is backed by a layer. In OS X, apps must explicitly enable Core Animation support by doing the following:

Link against the QuartzCore framework. (iOS apps must link against this framework only if they use Core Animation interfaces explicitly.) Enable layer support for one or more of your NSView objects by doing one of the following:

In your nib files, use the View Effects inspector to enable layer support for your views. The inspector displays checkboxes for the selected view and its subviews. It is recommended that you enable layer support in the content view of your window whenever possible. For views you create programmatically, call the view’s setWantsLayer: method and pass a value of YES to indicate that the view should use layers. Enabling layer support in one of the preceding ways creates a layer-backed view. With a layer-backed view, the system takes responsibility for creating the underlying layer object and for keeping that layer updated. In OS X, it is also possible to create a layer-hosting view, whereby your app actually creates and manages the underlying layer object. (You cannot create layer-hosting views in iOS.) For more information on how to create a layer-hosting view, see “Layer Hosting Lets You Change the Layer Object in OS X.”

More on: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/SettingUpLayerObjects/SettingUpLayerObjects.html

like image 161
valvoline Avatar answered Nov 08 '22 12:11

valvoline


I recently found myself in a very similar situation, having a cell based NSOutlineView that was blazing fast pre-Yosemite and almost crawled to a halt after upgrading to Yosemite.

In my experience, enabling layer-backing on the table view itself is not enough, you also have to enable it for the NSScrollView that contains your table view and it's NSClipView.

After making those changes my table view was up to speed again but experiencing some strange visual artifacts. Those might or might not be relevant in your situation since you're not using an source list NSOutlineView that uses the new vibrancy/transparency stuff in Yosemite.

In any case, those "effects" went away as soon as I converted to a view based table.

like image 39
lemonmojo Avatar answered Nov 08 '22 11:11

lemonmojo