Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Q. Textureは部分的に導入できますか?

Ca8210ff0ece2bb6f9fff5fd0770ea64?s=47 Muukii
September 13, 2018

Q. Textureは部分的に導入できますか?

巷で噂となっているPinterestによって開発されている、UIが猛烈に高速化されるTexture(AsyncDisplayKit)ですが、
非常に巨大なフレームワークであり、UIKitをラップする形でAPIが提供されています。
既存のアプリで「UIが重い!Textureを入れて速くしたい!」「でも途中から導入できるものなの?」という問題に対し、
実際のところ、導入は可能なのか?どのように?についてお話しします。

Ca8210ff0ece2bb6f9fff5fd0770ea64?s=128

Muukii

September 13, 2018
Tweet

Transcript

  1. Զίϯ 2018 Summer muukii eureka, Inc. Q. Texture͸෦෼తʹಋೖͰ͖·͔͢ʁ

  2. ☕ ⌚ About Me • Muukii <Hiroshi Kimura> • iOS

    Engineer at eureka, Inc. • Pairs Global Team • GitHub : @muukii
  3. None
  4. 1BJSTʹ͍ͭͯ !4

  5. 4PVUI,PSFB Japan Taiwan No.1 2017 release No.1 !5 1BJSTʹ͍ͭͯ ల։ࠃ

    ̐ͭͷϓϥοτϑΥʔϜ CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy
  6. None
  7. None
  8. Contents • Textureʹ͍ͭͯ • TextureΛ࢖͏ཧ༝ • Textureʹগ͠৮ΕΔ • TextureΛ෦෼తʹಋೖ͢Δ •

    TextureΛ࢖͍ͬͯ͘ʹ͋ͨͬͯ
  9. ⚠ ࠓճ͸Textureͷ঺հ͕ςʔϚͰ͢ɻ ొ৔͢Δαϯϓϧίʔυ͸ਖ਼͘͠ಈ࡞͠·͕͢ɺଟগ؆ུԽ͍ͯ͠ΔͨΊέʔεʹ ΑͬͯϓϥΫςΟε͸ҟͳΔ৔߹͕͋Γ·͢ɻ

  10. Textureʹ͍ͭͯ

  11. • AsyncDisplayKitͱ͍͏໊લͰFacebookͰ։ൃ • PinterestʹҠಈ͠Textureʹվ໊ • PinterestͷiOSΞϓϦͰશ໘తʹ࢖༻͞Ε͍ͯΔɻ • Pinterestͷૉ੖Β͍͠ಈ͖͸TextureʹΑΔ΋ͷ Textureʹ͍ͭͯ

  12. iPhone5s iPhone X

  13. What is the Texture? Textureʹ͍ͭͯ • UIॲཧΛߴ଎ԽɾඇಉظԽ͢Δ͜ͱʹΑͬͯಈ͖Λ׈Β͔ʹ͢ΔϥΠϒϥϦ • ݹ͍୺຤Ͱ΋60fpsग़͢͜ͱ͕໨త •

    ⚠ ϨΠΞ΢τ͚ͩͷϥΠϒϥϦͰ͸ͳ͍ • UIKitΛશମతʹϥοϓͯ͠໨తΛ࣮ݱ͢ΔΞϓϩʔν • ެ։͞Εͨ࣌ͷهࣄ • https://www.infoq.com/jp/news/2014/11/facebook-asyncdisplaykit-ios
  14. Before UIKit Developer Textureʹ͍ͭͯ

  15. After UIKit Developer Textureʹ͍ͭͯ Texture

  16. https://medium.com/@Pinterest_Engineering/re-architecting-pinterest-039-s-ios-app-e0a2d34a6ac2

  17. NodeΛ௨ͯ͠UIΛૢ࡞͢Δ • ϥΠϒϥϦར༻ऀ͸UIKitΦϒδΣΫτΛૢ࡞͢ΔͷͰ͸ͳ͘ɺ
 ASDisplayNodeͱ͍͏ΦϒδΣΫτΛ௨ͯ͠UIΛૢ࡞͢Δɻ • ASDisplayNode͸όοΫάϥ΢ϯυεϨου͔Β΋ΞΫηεՄೳ • ASDisplayNode -> UIView΁ͷల։͸Texture͕ඇಉظͰߦ͏

    • ల։͸MainThread͕UIૢ࡞Ͱ๩͚͠Ε͹ߋ৽ΛݟૹΔ • UIͷߋ৽Λࢭ·Βͳ͍Α͏ʹ͢ΔɾήʔϜΤϯδϯͬΆ͍ߟ͑ํ Textureʹ͍ͭͯ
  18. ༷ʑͳߴ଎ԽॲཧΛ࣋ͭ • ՄೳͳݶΓόοΫάϥ΢ϯυεϨουͰॲཧΛߦ͏ • UIͷϨεϙϯε଎౓͕࠷େԽ • UILabel΍UIImageView͸࢖ΘΕͣʹView or Layer ʹ

    Render • λοϓ൑ఆͷඞཁͷͳ͍΋ͷ͸CALayerͱͯ͠දࣔͰ͖Δ (isLayerBacked) • όοΫάϥ΢ϯυͰϝϞϦղ์Λߦ͏Ωϡʔ (releaseʹ΋ίετ͕͔͔ΔͨΊ) • ϨΠΞ΢τͷαΠζܭࢉ͸όοΫάϥ΢ϯυͰฒߦͰ࣮ߦՄೳ • CPUίΞͷଟ͍୺຤΄Ͳ༗ར Textureʹ͍ͭͯ
  19. UIView

  20. ASDisplayNode

  21. ASDisplayNode UIView Asynchronously

  22. Α͘࢖༻͢ΔΦϒδΣΫτ Core Objects

  23. UIViewʹ૬౰ ASDisplayNode : NSObject http://texturegroup.org/docs/display-node.html

  24. UIControlʹ૬౰ ASControlNode : ASDisplayNode http://texturegroup.org/docs/control-node.html

  25. UIButtonʹ૬౰ ASButtonNode : ASControlNode http://texturegroup.org/docs/button-node.html

  26. UILabelʹ૬౰ ASTextNode : ASDisplayNode http://texturegroup.org/docs/text-node.html

  27. UIImageViewʹ૬౰ ը૾ͷURLΛड͚෇͚ΔASNetworkImageNode΋͋Δ ASImageNode : ASDisplayNode http://texturegroup.org/docs/image-node.html

  28. UICollectionViewʹ૬౰ ASCollectionNode : ASDisplayNode http://texturegroup.org/docs/containers-ascollectionnode.html

  29. UICollectionViewCellʹ૬౰ ASCollectionNodeͰ࢖༻͢ΔCell ASCellNode : ASDisplayNode http://texturegroup.org/docs/cell-node.html

  30. UIKitͱTextureͷ࿈ܞ͸ൺֱత؆୯ • TextureΛ࢖͏͜ͱͰ׬શʹϩοΫΠϯ͞Εͯ͠·͏Θ͚Ͱ͸ͳ͍ • ؆୯ʹTexture͕ૢ࡞Λߦ͏UIView΁ΞΫηεՄೳ • ͦΕʹରͯ͠ΞχϝʔγϣϯΛߦ͏͜ͱ΋Մೳ • ߴ଎Խ͍ͨ͠෦෼ΛબΜͰTextureʹஔ͖׵͑Δ͜ͱ͕Մೳ Texture

    Overview
  31. UIKitͱTextureͷ࿈ܞ͸ൺֱత؆୯ • ͲͪΒ΋Մೳ (ৄࡉ͸ࠓճ͸ׂѪ) • TextureͷίϯϙʔωϯτΛAutoLayoutϫʔϧυͰར༻͢Δ • AutoLayoutϫʔϧυͷίϯϙʔωϯτΛTextureͰར༻͢Δ Texture Overview

  32. TextureΛ࢖͏ཧ༝

  33. • ׈Β͔ʹಈ͘UIΛఏڙ͍͔ͨ͠Β • Ͱ͖Δ͚ͩυϩοϓϑϨʔϜΛىͨ͘͜͠ͳ͍ TextureΛ࢖͏ཧ༝

  34. AutoLayout͸࣌ʹϘτϧωοΫͱͳΔ AutoLayout ManualLayout TextureΛ࢖͏ཧ༝

  35. ͻͱ·ͣɺϘτϧωοΫ͕ϨΠΞ΢τͱ෼͔ͬͨͱ͖ͷରࡦ • AutoLayout ConstraintsΛνϡʔχϯά͢Δ • AutoLayoutΛ΍ΊΔ (෦෼తʹͰ΋) TextureΛ࢖͏ཧ༝

  36. • ׈Β͔ʹಈ͘UIΛఏڙ͍͔ͨ͠Β • ՄೳͳݶΓυϩοϓϑϨʔϜΛى͜͞ͳ͍ • UIύϑΥʔϚϯενϡʔχϯά͸َ໳ • ϝΠϯεϨουͷ੍໿͕͋ΔͷͰ͙͢ʹݶքʹ౸ୡ͢Δ • ߴ଎

    & ϚϧνεϨουରԠͷΞϓϩʔν͕Ұ൪ڧྗ • Texture! TextureΛ࢖͏ཧ༝
  37. CellͷαΠζܭࢉΛ׬શʹࣗಈԽͭͭ͠ɺߴ଎ͳ·· • จࣈͷίϯςϯπ͸ΞΫηγϏϦςΟͳͲͷ؍఺ͰϢʔβʔʹΑΓจࣈαΠζ͕ม ߋͰ͖Δͷ͕๬·͍͠ UIFont.preferred~ • ࣮ݱํ๏ • AutoLayoutͰ࣮ݱ͢ΔͳΒ UIView.systemLayoutSizeFitting~

    • ManualLayoutͳΒؤுΔ NSString.bounding~ • TextureͳΒ଎౓Λམͱ͢͜ͱͳ͘AutoLayoutͷΑ͏ʹαΠζܭࢉ͕Մೳ TextureΛ࢖͏ཧ༝
  38. TextureΛ࢖͏͜ͱͷݒ೦ • Textureͷίϯϙʔωϯτ͸InterfaceBuilder͔Β͸࢖͑ͳ͍ • ϥΠϒϥϦ΁ͷґଘ͕ൃੜ͢Δ͜ͱ • ϥΠηϯεؔ࿈ (FacebookͷϥΠηϯε͕·ͩ࢒ͬͯΔ) • ߴ଎ԽͷͨΊʹϝϞϦ͸ଟ͘࢖༻͢Δ

  39. https://github.com/muukii/TextureBook Textureʹগ͠৮ΕΔ

  40. None
  41. None
  42. Card

  43. Image Card

  44. Image Card Title

  45. Image Card Title Detail

  46. Define Component Class

  47. In UIKit Create Card View final class CardView : UIView

    { private let imageView: UIImageView = .init() private let titleLabel: UILabel = .init() private let detailLabel: UILabel = .init() }
  48. In Texture Create Card View final class CardNode : ASDisplayNode

    { }
  49. In Texture Create Card View final class CardNode : ASDisplayNode

    { private let imageNode: ASImageNode = .init() private let titleNode: ASTextNode = .init() private let detailNode: ASTextNode = .init() }
  50. Define init class CardNode init(image: UIImage, title: String, detail: String)

    { super.init() }
  51. Set initial values init(image: UIImage, title: String, detail: String) {

    super.init() automaticallyManagesSubnodes = true titleNode.attributedText = ... detailNode.attributedText = ... imageNode.image = ... } class CardNode
  52. Define Layout

  53. Define layout class CardNode override func layoutSpecThatFits(_ constrainedSize: ASSizeRange) ->

    ASLayoutSpec { }
  54. ͜ΕΒΛ૊Έ߹ΘͤͯϨΠΞ΢τΛ࡞Γ্͛Δ ASLayoutSpec • ASWrapperLayoutSpec • ASStackLayoutSpec • ASInsetLayoutSpec • ASOverlayLayoutSpec

    • ASBackgroundLayoutSpec • ASCenterLayoutSpec • ASRatioLayoutSpec • ASRelativeLayoutSpec • ASAbsoluteLayoutSpec
  55. let imageSpec = ASRatioLayoutSpec(ratio: 1, child: imageNode) let body =

    ASStackLayoutSpec( direction: .vertical, spacing: 8, justifyContent: .end, alignItems: .start, children: [ imageSpec, titleNode, detailNode ] ) return ASInsetLayoutSpec( insets: .init(top: 8, left: 8, bottom: 8, right: 8), child: body )
  56. Card

  57. Image 1 : 1 Card let imageSpec = ASRatioLayoutSpec( ratio:

    1, child: imageNode )
  58. Card Title Detail let body = ASStackLayoutSpec( direction: .vertical, spacing:

    8, justifyContent: .end, alignItems: .start, children: [ imageSpec, titleNode, detailNode ] ) child: imageNode ) Image 1 : 1
  59. Image Card Title Detail return ASInsetLayoutSpec( insets: .init( top: 8,

    left: 8, bottom: 8, right: 8 ), child: body ) detailNode ] )
  60. Use Component

  61. Create Node Object Use Component let node = CardNode( image:

    UIImage(named: "sample")!, title: "Lorem Ipsum...", detail: "Lorem Ipsum..." ) addSubview(node.view)
  62. Calculate size that fits range ( Available in background thread

    ) node.frame.size = layout.size Use Component let layout = node.layoutThatFits( ASSizeRange( min: .init(width: 0.0, height: 250), max: .init(width: 240.0, height: .infinity) ) )
  63. None
  64. ߴ଎Խ͍ͨ͠ͱ͜ΖʹTextureΛ࢖͏ TextureΛ෦෼తʹಋೖ͢Δ

  65. Ͳ͜ʹ࢖͏͔ TextureΛ෦෼తʹಋೖ͢Δ • ΋ͬͱ΋ޮՌతͳ෦෼͸
 ʮCellͷߴ͕͞มಈ͢ΔUITableView, UICollectionViewʯΛ࢖༻͍ͯ͠Δͱ͜Ζ

  66. None
  67. UIViewController UIView UIView UICollectionView Cell Cell Cell ViewTree

  68. UIViewController CollectionNode CellNode ViewTree CellNode CellNode UIView UIView

  69. • ݱࡏUICollectionViewΛஔ͍͍ͯΔ৔ॴΛASCollectionNodeʹஔ͖׵͑Δ TextureΛ෦෼తʹಋೖ͢Δ

  70. Before UICollectionView -> ASCollectionNode class MyListViewController : UIViewController { let

    collectionView: UICollectionView = ... }
  71. After UICollectionView -> ASCollectionNode class MyListViewController : UIViewController { let

    collectionNode: ASCollectionNode = ... }
  72. Initialize ASCollectionNode UICollectionView -> ASCollectionNode let collectionNode: ASCollectionNode = {

    let layout = UICollectionViewFlowLayout() let node = ASCollectionNode(collectionViewLayout: layout) return node }()
  73. Add ASCollectionView of ASCollectionNode to view UICollectionView -> ASCollectionNode override

    func viewDidLoad() { let collectionView = collectionNode.view view.addSubview(collectionView) // Setup AutoLayout to CollectionView }
  74. DataSource, Delegate UICollectionView -> ASCollectionNode extension MyListViewController : ASCollectionDataSource, ASCollectionDelegateFlowLayout

    { }
  75. Return number of sections UICollectionView -> ASCollectionNode func numberOfSections(in collectionNode:

    ASCollectionNode) -> Int { return 1 }
  76. Reuse CardNode Create ASCellNode class CardNode : ASDisplayNode

  77. Change superclass - ASDisplayNode -> ASCellNode Create ASCellNode class CardNode

    : ASCellNode class CardNode : ASDisplayNode
  78. Return CellNode factory closure func collectionNode(_ collectionNode: ASCollectionNode, nodeBlockForItemAt indexPath:

    IndexPath) -> ASCellNodeBlock { return { // Call on Background Thread CardNode.init(...) } } UICollectionView -> ASCollectionNode
  79. Return constrained size for CellNode func collectionNode(_ collectionNode: ASCollectionNode, constrainedSizeForItemAt

    indexPath: IndexPath) -> ASSizeRange { return ASSizeRange( min: CGSize(width: collectionNode.bounds.width, height: 0), max: CGSize(width: collectionNode.bounds.width, height: .infinity) ) } UICollectionView -> ASCollectionNode
  80. Return constrained size for CellNode func collectionNode(_ collectionNode: ASCollectionNode, constrainedSizeForItemAt

    indexPath: IndexPath) -> ASSizeRange { return ASSizeRange( min: CGSize(width: collectionNode.bounds.width, height: 0), max: CGSize(width: collectionNode.bounds.width, height: .infinity) ) } UICollectionView -> ASCollectionNode Width = CollectionNode.width
 Height = 0 ... infinity
  81. None
  82. TextureΛ࢖͏ʹ͋ͨͬͯ

  83. ASViewControllerͷ࢖༻͸ඞਢͰ͸ͳ͍ • ASViewController : UIViewController ͕ఏڙ͞Ε͍ͯΔ • ը໘ͷදࣔঢ়ଶʹΑͬͯϝϞϦ؅ཧΛߦ͏ͳͲͷػೳΛఏڙ • ͨͩɺ࢖༻͸ඞਢͰ͸ͳ͍ͨΊɺطଘΞϓϦʹ͓͍ͯUIViewControllerͷܧঝઌ

    ͕มߋͮ͠Β͍έʔεͰ͸ແཧͯ͠࢖͏ඞཁ͸ͳ͍
  84. ΞΠςϜ͕େྔʹଘࡏ͢ΔϦετ (1ສ~ Λ௒͑ΔΞΠςϜ) Texture͕޲͔ͳ͍έʔε • ΧϝϥϩʔϧͷදࣔͳͲ • શͯͷCellNode͕ੜ੒͞ΕΔͷͰϝϞϦΛѹഭ͢Δ • ASCollectionGalleryLayoutDelegateͱ͍͏΋ͷ͕͋Δ͕ɺஈ֊తʹCellNode

    Λ࡞Δͱ͍͏ΞϓϩʔνͰ͋Γɺ࠷ऴతͳϝϞϦ࢖༻ྔʹมΘΓ͸ͳ͍ • ͜ͷ৔߹͸UICollectionViewΛ࢖༻ͯ͠ϝϞϦ࢖༻Λ཈͑Δ޻෉Λߦ͍ͳ͕Βର ࡦͨ͠ํ͕ྑ͍
  85. Texture࢖͏΂͖ͳͷʁ • Textureಋೖͷݕ౼Λߦ͏લʹ·ͣύϑΥʔϚϯεͷϘτϧωοΫΛ͔ͬ͠Γௐࠪ ͠·͠ΐ͏ɻ • ϥΠϒϥϦґଘͱֶशίετͱϋϚΓίετ͕ൃੜ͢ΔͷͰ֮ޛ͸ඞཁ • ҆ఆతʹ55fps ~ 60fps͕ཉ͍͠ͳΒࢼ͢Ձ஋͋Γ

  86. Textureͷ಺෦࣮૷͸͔ͳΓษڧʹͳΔ • Texture͸ߴ଎͕ͩɺ಺෦Ͱ͸Apple͕ఏڙ͍ͯ͠Δ΋ͷΛ্खʹ࢖͍ͬͯΔ • UIKit, CoreGraphics, CoreText, CoreAnimation (C++΋) ͷѻ͍ํ͸ࢀߟʹͳΔ͜

    ͱ͕ଟ͍ɻ • ಺෦࣮૷Λগ͠஌Δ͚ͩͰ΋TextureΛ࢖͑ͳ͍؀ڥͰ΋ߴ଎Խ͢ΔͨΊͷखஈ͕ ૿͑ͨ
  87. ΞϓϦͷߴ଎Խͷ૬ஊ͸͍ͭͰ΋! • ʮTexture࢖͍͍ͨͱࢥͬͯΔ͚ͲɺϢʔεέʔεʹ͋ͬͯΔʁʯ • ʮTexture࢖ͬͯΔ͚Ͳɺ͜͏͍͏࣌Ͳ͏ͯ͠Δʁʯ • ʮଞͷϨΠΞ΢τΤϯδϯ͸Ͳ͏ͳΜͰ͠ΐʁʯ • ͳͲͷ͓࿩͸͍ͭͰ΋ʂ •

    Τ΢ϨΧͰiOS Android΋͘΋͘ձ΍ͬͯΔͷͰੋඇ༡ͼʹ͖͍ͯͩ͘͞ʂ • https://eure.connpass.com/event/100159/
  88. The sample codes using Texture. https://github.com/muukii/TextureBook Thank you