非同期UI描画による高速なアプリケーションの実装

06e251dd7c57b30b6771050dbe88683b?s=47 fumito-ito
September 03, 2018

 非同期UI描画による高速なアプリケーションの実装

iOSアプリケーションの高速化においてメインスレッドをブロックするUIの描画コストは無視できない問題です。

日経電子版アプリでは非同期なUI描画を実現するTexture(AsyncDisplayKit)を導入し、大量のテーブルをスムーズに描画しています。
本セッションではTextureの検討から具体的な導入ステップ、導入にあたって遭遇したトラブルと対応方法について紹介します。

-----

このスライドは俺コン 2018 Summer Day 1 (https://orecon.connpass.com/event/94858/) および iOSDC 2018 Reject Conference Day 1 (https://iosdc-reject-conference.connpass.com/event/93314/) で発表予定の内容です。

06e251dd7c57b30b6771050dbe88683b?s=128

fumito-ito

September 03, 2018
Tweet

Transcript

  1. 1 ඇಉظUIඳըʹΑΔߴ଎ͳ ΞϓϦέʔγϣϯͷ࣮૷

  2. 2 ύϑΥʔϚϯε ؾʹͯ͠·͔͢ʁ

  3. 3 “Most apps target a frame rate of 60 FPS,

    Equivalent to 16.67 ms per frame.” https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/ MTLBestPracticesGuide/FrameRate.html
  4. 4 16 ms…

  5. 5 ίετͷߴ͍ॲཧ • ϨΠΞ΢τ • UIΛ഑ஔ͢Δ • ςΩετΛ഑ஔ͢Δ • ΦϑεΫϦʔϯϨϯμϦϯά

  6. 6 ͍͍ͩͨରԠࡁΈ https://speakerdeck.com/ikait/the-way-to-60-fps

  7. 7 ͕ͬ…ବ໨ͬ…!

  8. 8 UITableView͕େྔʹฒͿ

  9. 9 UIͷඳը͸ϝΠϯεϨουͰ࣮ߦ ը໘ͷඳը͸16msҎ಺ʹ׬ྃ v.s.

  10. 10

  11. 11 ʮUIͷඳը͸ϝΠϯεϨουͰ ɹ࣮ߦ͠ͳͯ͘͸ͳΒͳ͍ʯ͸ ຊ౰͔

  12. 12 UIͷඳը͸෼ղՄೳͰ͋Δ ϨΠΞ΢τͷܭࢉ ը૾ͷσίʔυ จࣈ૊Έͷܭࢉ ϨΠϠʔॲཧ ը໘΁ͷඳը

  13. 13 ϝΠϯεϨουҎ֎Ͱ͍͚ͦ͏ ϨΠΞ΢τͷܭࢉ ը૾ͷσίʔυ จࣈ૊Έͷܭࢉ ϨΠϠʔॲཧ ը໘΁ͷඳը

  14. 14 ͍͚ΔͬΆ͍

  15. 15 Texture • FacebookͷUIϑϨʔϜϫʔΫ͕OSSԽ͞Εͨ΋ͷ
 (౰࣌͸AsyncDisplayKit) • ݱࡏ͸PinterestͰओʹར༻͞Ε͍ͯΔ • ϝΠϯεϨουͷ֎ͰUIඳըΛ࣮ߦ͢Δ͜ͱͰ׈Β͔ ͳUIΛ࣮ݱ͢Δ

  16. 16 Texture͕ϝΠϯεϨου͔Β औΓআ͘ॲཧ ϨΠΞ΢τͷܭࢉ ը૾ͷσίʔυ จࣈ૊Έͷܭࢉ ϨΠϠʔॲཧ ը໘΁ͷඳը

  17. 17 Texture before / after Before After

  18. 18 ೔ܦిࢠ൛ʹ͓͚Δ Texture΁ͷҠߦ

  19. 19 લఏ • RxSwift + MVVMΞʔΩςΫνϟ • ϨΠΞ΢τΤϯδϯ͸AutoLayout

  20. 20 ஈ֊తಋೖ • Ұ൪଎͍ͨ͘͠ը໘Λஔ͖׵͑ • 1ϲ݄͘Β͍Ͱௐࠪ + ࣮૷ • ViewController,

    ViewΛஔ͖׵͑ • ςʔϒϧͷࠩ෼ߋ৽Λ࣮૷ • ViewController୯ҐͰஔ͖׵͍͑ͯͬͨ • 1 VC / 2 ~ 3ਓ೔͘Β͍ͷϖʔε • Viewͷछྨ͕ଟ͍΄Ͳ͕͔͔࣌ؒΔ
  21. 21 Ҡߦεςοϓ • Nodeʹஔ͖׵͑ • NodeContainerʹஔ͖׵͑ • ίϨΫγϣϯΫϥεͷࠩ෼ߋ৽ରԠ • ࠷దԽ

  22. 22 Nodeʹஔ͖׵͑ • Node • UIView, UITableViewCellͳͲͷ୅ସ • ASDisplayNode, ASCellNodeͳͲ

    • ϨΠΞ΢τΤϯδϯ + εϨουηʔϑ • Nodeʹ௚઀ੜ͍͑ͯΔϓϩύςΟ͸શͯεϨουηʔϑ • CSS FlexboxϥΠΫͳϨΠΞ΢τΤϯδϯΛར༻ • node.view, node.layer͔ΒجఈͷΦϒδΣΫτʹ΋ΞΫηεͰ͖Δ • ͕ɺεϨουηʔϑͰ͸ͳ͍ͷͰཁ஫ҙ
  23. 23 ϨΠΞ΢τ͸CSS FlexboxϥΠΫͳAPIΛར༻੍ͯ͠ޚ͢Δ

  24. 24 UIWebViewͳͲ༻ҙ͞Ε͍ͯͳ͍View͸ASDisplayNodeͷίϯετϥΫλΛ ར༻͢Δ

  25. 25 NodeContainerʹஔ͖׵͑ • NodeContainer • UIViewController, UITableViewͳͲͷ୅ସ • ASViewController, ASTableNodeͳͲ

    • جຊ͸Nodeͱಉ͡ • delegate͸ϝΠϯεϨουͰಈ͘΋ͷͱͦΕҎ֎ͷεϨουͰಈ͘΋ͷ
 ͕ڞଘ͍ͯ͠ΔͷͰ஫ҙ • ASTableNode, ASCollectionNode͸Cellͷ࠶ར༻͕ͳ͍ͳͲ
 ಛ༗ͷҧ͍΋͋Δ
  26. 26 • UIViewControllerͷஔ͖׵͑͸ൺֱత୯७ • Delegate͸ඇಉظʹ࣮ߦ͞ΕΔؔ਺Λฦ͢ܗࣜʹ

  27. 27 ίϨΫγϣϯͷࠩ෼ߋ৽ରԠ • TextureͰ͸Cellͷ࠶ར༻Λ͠ͳ͍ͷͰreloadDataͷ
 ίετ͕ߴ͍ • TableNode, CollectionNode͸ݪଇͱͯࠩ͠෼ߋ৽Λར༻͢Δ • RxSwiftͱซ༻͍ͯ͠Δ৔߹͸ࠩ෼ܭࢉϥΠϒϥϦͷ


    RxASDataSources͕ར༻Ͱ͖Δ • https://github.com/RxSwiftCommunity/RxASDataSources
  28. 28 ࠷దԽ • Batch FetchingΛ࢖͏ • TextureͰ͸UIKitΑΓ΋ࡉ͔͘ϓϦϩʔυͷঢ়ଶΛ੍ޚͰ ͖Δ • ը૾ͷಡΈࠐΈɺίϨΫγϣϯͷઌಡΈͳͲ͸ϓϦϩʔυ

    ༻ͷίʔϧόοΫΛར༻͢Δ͜ͱͰ࠷దԽ͢Δ http://texturegroup.org/docs/intelligent-preloading.html
  29. 29 ࠷దԽ • Layer Backing • ֘౰͢ΔASDisplayNode͕ը໘ʹඳը͞ΕΔͱ͖ʹ
 CALayerͷΦϒδΣΫτͱͯ͠ඳը͞ΕΔ • λονΠϕϯτΛऔΒͳ͍ΦϒδΣΫτ͸ͱΓ͋͑ͣONͰྑ͍

    • Subtree Rasterization • ֊૚Խ͞ΕͨUIViewΛҰͭͷ֊૚ʹ·ͱΊͯඳը͢Δ
  30. 30 ϋϚΓͲ͜Ζ • ϨΠΞ΢τγεςϜͷ੾Γସ͑ • εϨουʹ·ͭΘΔ໰୊ • UIKitͱซ༻͢ΔͱVoiceOver͕յΕΔ • Carthageؔ࿈ͷτϥϒϧ

  31. 31 ϨΠΞ΢τγεςϜͷ੾Γସ͑ • AutoLayoutΛશ෦ஔ͖׵͑Δඞཁ͕͋ΔͷͰ
 ׳ΕΔ·ͰҰ൪޻਺Λ৯͏ • TextureͷެࣜαΠτʹམͪึर͍తͳαϯϓϧ͕
 ॻ͍ͯ͋ΔͷͰΦεεϝ • http://texturegroup.org/docs/automatic-layout-examples-2.html

  32. 32 εϨουʹ·ͭΘΔ໰୊ • ϩΨʔͱ͔؆қόοϑΝͱͯ͠DictionaryΛ࢖͍ͬͯΔ
 Օॴ͕Ϋϥογϡ͢Δ • SwiftͷDictionary͸εϨουηʔϑͰ͸ͳ͍ͷͰ஫ҙ • ThreadSafeDictionaryΛ࡞͓ͬͯ͘ͱָ •

    ϝΠϯεϨουνΣοΧʔΛ࢖ͬͯҰ௨Γςετ͠·͠ΐ͏
  33. 33 VoiceOver͕յΕΔ • ʮASViewControllerʹஔ͖׵͚͑ͨͲNodeͷஔ͖׵͑
 ɹͯ͠ͳ͍ͷͰaddSubViewΛ࢖͍ͬͯΔʯ͔ͭ
 ʮͦͷViewControllerͷ਌΋ASViewControllerʯ
 ͱ͍͏ঢ়گͰൃੜ͢Δ • UIKitͱTextureͰAccessibilityElementͷ୳ࡧύε͕
 ҟͳΔ͜ͱ͕ݪҼ

  34. 34 खಈͰAccessibilityElementsΛࢦఆ͢Ε͹ճආͰ͖Δ

  35. 35 Carthageؔ࿈ͷτϥϒϧ • ͦ΋ͦ΋࠷৽ͷTexture 2.7͕CarthageͰΠϯετʔϧ
 Ͱ͖ͳ͍… • masterͰ͸ղܾ͍ͯ͠Δ • աڈʹ΋༷ʑͳ໰୊͕͋ͬͨ

    • ࣮ߦ࣌ΤϥʔʹͳΔɹ<- ղফࡁΈ • ը૾Ωϟογϡ͕ʢ੩͔ʹʣແޮʹͳΔɹ<- ݱ໾ͷόά
  36. 36 ࣮ߦ࣌ΤϥʔʹͳΔ • 2.6Ͱݱ໾ͷ໰୊ • 2.6͸CarthageͰਖ਼ৗʹΠϯετʔϧͰ͖Δ
 ࠷৽ͷόʔδϣϯ… • pinterest/PINCacheͱͷ૬ੑͷ໰୊ͳͷͰCartfileͰ
 ໌ࣔతʹ”3.0.1-beta.6"Λࢦఆ͢Δ͜ͱͰղফ͢Δ

  37. 37 ASPINRemoteImageDownloader.h / .mΛϓϩδΣΫτʹ௥Ճ͢Δ͜ͱͰ ճආͰ͖Δ ը૾Ωϟογϡ͕ແޮʹͳͬͯΔ

  38. 38 Textureͷྑ͍ͱ͜Ζ • ViewModelҎԼΛॻ͖׵͑Δඞཁ͕ͳ͔ͬͨ • ߴ͞ܭࢉͳͲΛؚΊͨϨΠΞ΢τॲཧ͕Viewͷ
 Ϋϥε಺Ͱ׬݁͢Δ • ϓϦϑΣονɺը૾ͷ஗ԆϩʔυͳͲͷॲཧ͕
 ؆୯ʹඳ͚ΔΑ͏ʹαϙʔτ͞Ε͍ͯΔ

  39. 39 ·ͱΊ • UIΛޮ཰Α͘ඳը͢ΔͨΊʹϝΠϯεϨουҎ֎ͰUIΛ
 ߋ৽Ͱ͖ΔTextureΛ࠾༻ͨ͠ • TextureΛ࠾༻͢Δ͜ͱͰUIඳըͷύϑΥʔϚϯε͕
 ޲্ͨ͠ • ݱঢ়ͷTextureͰ͸Carthageؔ࿈ͳͲ͍͔ͭ͘ͷ໰୊͕


    ଘࡏ͢Δ
  40. 40 RxASDataSourceͷ ίϯτϦϏϡʔλʔ ืूதͰ͢ɻ @fumito_ito fumito-ito