Scroll Performance & macOS Ventura

I recently switched to using macOS Ventura on my MacBook M1 Pro as the primary working device.

This required a change in my workflow and given how these machines work, Elytra would always be up to date and ready with new articles when I opened the lid the morning.

I quickly began noticing abysmal scorlling performance in the article view of the app. On a second passs, I noticed everything about the article view was slow: rendering, scrolling, and resizing.

I ran the AppStore build on my macOS 12 system and did not observe the same, but this Mac had 64GB of memory, a dedicated desktop-class GPU and a 14-core workstation chip, all liquid cooled. So I began to wonder if the M1 Pro chip was being “lazy”.

I still wondered if I am to blame for this, I turned to instruments to analyze the rendering performance and behold: TextKit2 bites me again.

Intruments showing rendering callstacks for Elytra's article reader view

Now that I know what’s causing the issue, I turned to the internet: Apple’s Dev Forums, StackOverflow, various macOS engineering blogs and even mailing lists (those are still very very cool).

It turns out, I’m not the only one to be bit by TextKit 2’s erractic behaviour, incomplete APIs and a lack sensible documentation apart from a few WWDC videos. To make matters worse, unlike TextKit 1, this was no “drop-in” replacement like Apple claimed it to be and is an automatic opt-in when compiling with the latest SDKs.

In a sample project, TextKit2 rendering was atleast 70% slower than TextKit1. Worse, when resizing a window.

Luckily for me, I found this post by Daniel Jalkut

The simple workaround, for the time being anyway, is to force your text view to use TextKit 1. As explained in the WWDC excerpt above, this is as simple as asking it once for its layout manager, which will cause it to rebuild its entire text architecture to suit the TextKit 1 way of functioning

and the oneliner: let _ = myTextView.layoutManager

Because of how Elytra is archictected, this patch totaled in as a +1 -0 commit. Sweet. All text-rendering is mostly handled by a single View: Paragraph which other views like Heading, List, Blockquote, etc. are subclasses of.

With that fix in place, the article view was back to rendering, scrolling, and resizing at full 120Hz (sweet sweet ProMotion goodness).

This will become available as a fix in the upcoming builds v2022.11.3 (485) which are currently waiting for review.

If you’re using the notarized releases, the latest build is immediately available for download:

If you’re also building and shipping a Catalyst app, and wondering if you’re app also may be affected by this issue: unless you are intentionally poking at the layout managers, containers of the text views, you shouldn’t have to worry. But if you are and notice similar issues, try forcing the text view to use TextKit 1 instead and see how that works out.