Created
June 19, 2018 12:18
-
-
Save niwatako/201e21a14289864fc1c43de2e4c2c78a to your computer and use it in GitHub Desktop.
UIKitによるパフォーマンス向上方針 #roppongiswift #CodePiece
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ### @stzn3 UIKitによるパフォーマンス向上方針 | |
| 大きく分けて3つあったが、最初とかぶったのでそこは端折ります。 | |
| 都内某所の受託開発会社勤務、本名は珍しいので秘密です。 | |
| Swift, Android(kotlin), JS, C#, Java, PHP。。。など | |
| Session 202/219/220/407 より | |
| Scrolling、Memory, Autolayout のパソーマンスが改善されている | |
| #### Scrolling | |
| Scrollingは何もしなくても改善されている。スクロールで画面がかくつくフレーム落ちがある。CellForRowAtやLayoutSubviewsで重い処理をしているとそこで引っかかる。iOS10でPrefetchが導入されて、セルを表示するより前にデータを取ることで、CPUのスパイク、一時的使用の急増を防いでいる | |
| 書いたから呼んでね | |
| 【Swift】この時期だから見直すiOS10の新機能 UITableView UICollectionViewの改善とPre-Fetching API | |
| https://qiita.com/shiz/items/66ae7e772d315dadf7d4 | |
| Prefetchがかぶるとスパイクが結局起きてしまっていた | |
| iOS12では、Prefetdhがかぶらないようにスケジューリングが可能になった | |
| でもまだある。何もしていないときに急にフレームが落ちる事がある。何もしていなかったからこその、消炎絵モードからのCPUの立ち上がりに時間がかかってしまうのが問題。 | |
| その改善のためにramp up の改善が行われた。CPUの立ち上がりの指示を事前にControllerに支持することで必要なCPU料を推測して立ち上げに備える。それでCPU使用にまに合うようになった。 | |
| #### Memory | |
| Memory Buffer:連続したメモリ領域 | |
| ImageBufferというのがある。 | |
| ある画像を表現したBufferで各要素が1ピクセルを表す。画像のデータと同じサイズになる。 | |
| FrameBuffer | |
| Image Bufferの一種でViewのレンダリング結果を保持している。フレームレートに合わせて更新している。 | |
| DataBuuffer | |
| 画像データのメタデータ画像を保持している。画像サイズや圧縮形式を保持。 | |
| Backing Store: デコードしたImageBufferを内部に保持する。保持する分メモリを消費する。iOS12から画像に使われている色などからサイズを自動計算するようになった。 | |
| 白黒でもカラーでも同じだけ確保されていたが、iOS12からは、たとえば色付きで2.2MBのやつも白黒は275kbで済むようになりました。 | |
| UIImage、UIImageViewは何をしているのか。 | |
| UIImageが画像をロードしてImageBufferにデコードしている。 | |
| デコードにはCPUを使う。デコードしたらImageBufferになるので、永続的にメモリアロケーションを要する。 | |
| 保持するデータを少なくするには? | |
| Bufferに保持されるデータサイズを事前に小さくしてメモリ圧迫を防ぐ。DownSampling。 | |
| キャッシュするデータのリュを、Decodeと同時に保存するのではなくて、保存するタイミングをずらすことで、小さくしたデータを保存するようにしている。 | |
| サンプルで、ImageViewをひたすら読み込むアプリの例、492MB使いました。 | |
| これをdownSamplingします。50.1MBに減りました。 | |
| 画像が重くて困ったら思い出してください。 | |
| 発表資料に出てきていますのでそちらからご確認ください。 | |
| #### 画像リソース | |
| ImageAssetsを使うのが推奨、名前が検索に最適化され、キャッシュが最小、インストールデバイスに合わせてサイズが最適化される、Vector Artwork が活用される | |
| #### CustomUIViewは使うべきか | |
| drawメソッドを上書きするようなカスタムViewはやめたほうがいい | |
| UIView.drawはBackingStoreを自動で利用する。ViewのPixcelサイズがBackingStoreの大きさ | |
| iOS12からWideColorがデフォルトでtrue | |
| CALayer.ContentsFormatでWide ColorをOffにしていた場合、iOS12ではこれを使うといろいろうまく動かないので注意 | |
| drawをつかわない: backgroundColorは直接Frame Bufferに書き込める | |
| UIImageViewで代用できないか、他にもBackingStore使わない方法を考える | |
| MaskingView | |
| (筆記おいつかない) | |
| UIImageはモノクロの画像をカラーにできる、tintColorを使う。FrameBufferに直接書き込まれるのでメモリ節約。Image SetでTempleteImageを選ぶやつ。 | |
| UILあべlではなるべくモノクロカラーをリユする。 | |
| UIImageViewは最適化されているので使うことでUIViewよりメモリを抑えることができる | |
| UIGraphicsImageRendererを使う | |
| ImageBufferの最適化 | |
| WideColor自動サポート、prefer.....←depricatedになってて謎 | |
| Autolayoutのパフォーマンスが改善されました | |
| 11.4と12.0で試したら、まぁ若干改善されたかなという感じではあったけど、大幅かというと疑問。 | |
| WindowにインナーオブジェクトといてEnginが入っている。View追加されたりすると、Viewは計算前の制約Equationを作る。Acriveになったらこの方程式のような状態のものをEnginに渡す。 | |
| そこで相対値や、最低値、最大値などを計算する。 | |
| 計算されたものは、Variableという計算結果変数に入れられる。 | |
| ViewはVariableを参照してEnginに対して変更があるか聞いて、変更があればViewはsuperView.setNeedsLayoutを呼ぶ。 | |
| 変更を受けた親は、Layoutを親から子に伝播する。LayoutSubviewsの中では、Viewが値なんだっけとEnginに確認、返された値を下にSubviewsに位置大きさを指示する。 | |
| updateconstraintsで制約を変えるとこれを繰り返し行うことになる。 | |
| `Enginはキャッシュであり制約関係の追跡者である。` 何度も設定しなくてもいいということかな? | |
| 必要なものにだけ必要な制約をつけましょう。 | |
| 削除して追加の繰り返し離し、intrinsicConstentsizeがいらない場合はオーバーライドして UIView.noIntrinsicMetricを使うと処理を省略できる。 | |
| UIKitは見えないところで進化しています。意識すると改善できる、間違えると悪化する可能性もある。 | |
| 用法用量を守って正しく使いましょう。 |
Author
niwatako
commented
Jun 20, 2018
- https://twitter.com/stzn3/status/1009340999317852160
- https://speakerdeck.com/shiz/20180619-roppongi
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment