Help us understand the problem. What is going on with this article?

Texture(旧AsyncDisplayKit)の仕組みを理解する

More than 1 year has passed since last update.

Textureは60fpsを実現するiOS用の高速非同期UIフレームワークです。Pinterestが開発しており、Pinterestアプリでも使用されています。以前はAsyncDisplayKitという名前でFacebookが開発していました。

「Async」という以前の名称からも分かるように、Textureは「非同期」であるというのが大きな特徴です。iOSのUIKitはすべてメインスレッドで操作する必要があり、それがパフォーマンスのボトルネックになる場合があります。例えばTableViewのCellを表示する場合、UIKitではひとつのスレッドがCellを上から順番に描画しています。Textureでは複数のスレッドが複数のCellを同時に描画するため、パフォーマンスが格段に上がります。

Textureの仕組み

Textureは内部的にUIKitのコンポーネントを利用しています。例えばボタンであるASButtonNodeは内部的にUIViewを使っています。またテーブルビューであるASTableNodeは内部でUITableViewを利用しています。それではTextureはどのように非同期でUIを作り上げているのでしょうか。

その答えはCALayerです。具体的に言うと、CALayer.contentsにオフスクリーン画像(UIGraphicsBeginImageContextWithOptionsで作成するUIImage)を入れることで非同期を実現しています。iOSではテキストの幅や高さを取得したり、テキストや画像を描画したりするコードはメインスレッド以外でも動作します。Textureはこれを利用して、例えばテーブルビューのセルを描画する際に、セルと同じサイズのオフスクリーン画像を作り、そこにセルのコンテンツを描き込む処理を別スレッドで行なっています。そして出来上がった画像をCALayer.contentsにセットするところだけをメインスレッドで実行することにより、メインスレッドの負荷を最小限に抑え、60fpsを実現しています。

UIが表示されるまでの流れ

ASTableNodeを例にして、Textureがどのように動いているのかを見てみます。ASTableNodeを作成してサブノード(Textureのビュー階層)に追加すると、内部的にUITableViewが作成され、画面に追加されます。そしてUITableViewのDataSourceであるtableView(_:cellForRowAt:)が呼ばれたタイミングで、UITableViewCellが作成されます。

ASTableNodeはPreloadingに対応しており、UITableViewCellが作成される以前からデータが準備されます。この時、ASTableNodeのDataSourceであるtableNode(_:nodeBlockForRowAt:)が呼ばれます。ASTableDataSourceではセルを返すのではなく、セルを描画するASCellNodeクラスを返します。

ASCellNodeは内部的にUIViewを保持しており、非同期でUIを表示します。例えばASTextCellNodeはTextKitを利用してUIImageにテキストを描画し、それをCALayer.contentsにセットします。このビューがUITableViewCellに追加されてUITableViewにコンテンツが表示されます。

Textureの他のUIコンポーネントも内部でUIKitのビューを持ち、UIImageに描画してCALayer.contentsに入れるような仕組みでUIを表示しています。

Textureのデメリット

このようにいいことずくめに見えるTextureですが、デメリットもあります。それはメモリとバッテリーを多く消費するということです。UIKitと比べて、画像を作成して描画する分だけメモリとバッテリーを消費します。そしてASTableNodeやコレクションビューのASCollectionNodeの場合は、セルが画面に表示されるタイミングで毎回画像の作成と描画が発生するため、その影響は小さくないと考えます。

またTextureの導入には大きなコードの変更が必要となります。UIKitのViewはTextureのNodeに、そしてViewControllerはASViewControllerに置き換える必要があります。またTextureではAuto Layoutも使えないため、レイアウトコードも書き直す必要があります。

Textureの導入はアプリ毎に様々な側面から判断すべきです。

tamadeveloper
iOS+Mac用のカレンダーアプリを作っています。
https://firstseed.io/jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした