$30 off During Our Annual Pro Sale. View Details »

レガシーなアプリケーションの 60fps化を目指す為にやっていること

レガシーなアプリケーションの 60fps化を目指す為にやっていること

iOSDC2018

8/31 17:40
@早稲田大学理工学部 西早稲田キャンパス 63号館

satoshin21

August 31, 2018
Tweet

More Decks by satoshin21

Other Decks in Programming

Transcript

  1. Copyright © 2017 eureka, Inc. All rights reserved.
    What we’ve done to get High Performance in our Legacy Application
    ϨΨγʔͳΞϓϦέʔγϣϯͷ
    60fpsԽΛ໨ࢦ͢ҝʹ΍͍ͬͯΔ͜ͱ

    View Slide

  2. Copyright © 2017 eureka, Inc. All rights reserved.
    2
    Introduce
    FVSFLB *OD
    1BJSTJ04"QQMJDBUJPO&OHJOFFS
    ໺ྑΧϝϥϚϯ΍ͬͯ·͢ඃࣸମʹծ͑ͯΔͷͰࣸਅࡱΒΕͯԼ͍͞
    @satoshin21

    View Slide

  3. Copyright © 2017 eureka, Inc. All rights reserved.
    3
    Agenda
    1BJSTͷ঺հͱJ04νʔϜͷ՝୊
    ॲཧϑϩʔΛ௥͍΍͍͢ΞʔΩςΫνϟͷಋೖ
    Ϩεϙϯεͷ࠷దԽಡΈࠐΈ଎౓ߴ଎Խ
    ໨ࢦͤGQT$PMMFDUJPO7JFXνϡʔχϯά
    Ռͨͯ͠GQTͰվળͨ͠ͷ͔ʁ

    View Slide

  4. Copyright © 2017 eureka, Inc. All rights reserved.
    Pairsͷ঺հ & iOSνʔϜͷ՝୊

    View Slide

  5. View Slide

  6. Copyright © 2017 eureka, Inc. All rights reserved.
    6
    ྺ࢙Λ࣋ͭPairs
    αʔϏε։࢝͸೥݄
    ೥݄ʹ1BJSTGPSJ04W͕ఏڙ։࢝
    ೥݄ʹϑϧεΫϥον

    View Slide

  7. Copyright © 2017 eureka, Inc. All rights reserved.
    7
    2018೥ݱࡏͷ՝୊
    0CKFDUJWF$͕ࠜװΛ୲͍ͬͯΔ෦෼͕͋Δҝɺ4XJGUͷϙςϯγϟϧΛ࠷
    େݶੜ͔ͤͳ͍
    ػೳ௥Ճɾվળεϐʔυ্͕͕͍ͬͯΔ͕ɺϓϩμΫτ͕ͦͷεϐʔυʹ
    ௥͍͚͍ͭͯͳ͍
    ٕज़ෛ࠴͕ஷ·ΓɺϓϩμΫτͷύϑΥʔϚϯεʹӨڹ͕ग़࢝Ί͍ͯΔ
    ͔Β࡞Γ௚͍͕ͨ͠ɺίετ͕ߴ͍

    View Slide

  8. Ͳ͏ʹ͔վળ͍ͨ͠

    View Slide

  9. ͍͖ͳΓશͯΛ࡞Γม͑ΔͷͰ͸ͳ͘
    શମ࠷దԽʹ޲͚ͯҰาͮͭਐΉ

    View Slide

  10. Copyright © 2017 eureka, Inc. All rights reserved.
    10
    શମ࠷దͱ෦෼࠷ద
    શମ࠷ద΁ͷಓ͸ҰͭͰ͸ͳ͍
    ෦෼తͳ࠷దԽΛߦ͍ɺͦΕΛϓϩμΫτશମʹల։͍ͯ͘͠
    શମ࠷దΛݟਾ͑ͨ෦෼࠷దΛߦ͏

    View Slide

  11. ෦෼࠷దΛ͢ΔͷͰ͋Ε͹ɾɾ

    View Slide

  12. Ϣʔβ͕ޮՌΛ࣮ײ͠΍͍͢
    & ໢ཏతͳػೳ͕ଘࡏ͢Δ

    View Slide

  13. ϢʔβΛ͕͢͞ը໘

    View Slide

  14. Copyright © 2017 eureka, Inc. All rights reserved.
    14
    ͕͢͞ը໘ʹܾΊͨཧ༝
    ϩάΠϯޙɺҰ൪࠷ॳʹදࣔ͞ΕΔը໘
    Ϣʔβʹ࠷΋ར༻͞ΕΔը໘ͷҰͭ
    ϓϩμΫτ಺Ͱԣల։Մೳͳ༷ʑͳػೳ
    $PMMFDUJPO7JFX Ϧϩʔυɺ௥ՃಡΈࠐΈɺ༷ʑͳσʔλΛҰཡදࣔ

    View Slide

  15. Copyright © 2017 eureka, Inc. All rights reserved.
    15
    ͕͢͞ը໘ͷ՝୊
    ൚༻Խͷҝͷଟ૚ܧঝͰॲཧ͕௥͍ʹ͍͘
    Ϣʔβͷσʔλྔ͕ଟ͍ҝɺϩʔυʹ͕͔͔࣌ؒ
    Δ
    εΫϩʔϧ࣌ʹΨλͭ͘
    ฏۉdGQT J1IPOFJ04Ͱܭଌ

    ※ Ϣʔβը૾͸σϞ༻ʹ༻ҙͨ͠΋ͷʹͳΓ·͢

    View Slide

  16. Copyright © 2017 eureka, Inc. All rights reserved.
    16
    Τ΢ϨΧ ͷ iOS/Android/Web Engineer
    6*69ʹ߆Γ͕ڧ͍ 6*ψϧψϧܯ࡯͕ৗற

    *OTUBHSBN΍5JOEFSͳͲΠέͯΔ6*69Λ໨ࢦ͢

    View Slide

  17. Copyright © 2017 eureka, Inc. All rights reserved.
    17
    ෦෼࠷దͷ໨ඪ
    ॲཧϑϩʔΛ௥͍΍͍͢ΞʔΩςΫνϟͷಋೖ
    ϢʔβͷϨεϙϯεΛ࠷దԽಡΈࠐΈͷߴ଎Խ
    ໨ࢦͤGQT

    View Slide

  18. Copyright © 2017 eureka, Inc. All rights reserved.
    ॲཧϑϩʔΛ௥͍΍͍͢
    ΞʔΩςΫνϟͷಋೖ

    View Slide

  19. Copyright © 2017 eureka, Inc. All rights reserved.
    19
    ݱࡏͷ͕͢͞ը໘
    'BU7JFX$POUSPMMFS
    ͕͢͞ը໘Ͱ͸ͭͷ7JFX$POUSPMMFSΛܧঝ͢Δଟ૚ߏ੒

    View Slide

  20. Copyright © 2017 eureka, Inc. All rights reserved.
    20
    ଟ૚ܧঝ͞ΕΔViewController
    "CTUSBDU
    7JFX$POUSPMMFS
    ͕͢͞ը໘
    7JFX$POUSPMMFS
    "CTUSBDU
    7JFX$POUSPMMFS
    "CTUSBDU
    7JFX$POUSPMMFS
    "CTUSBDU
    7JFX$POUSPMMFS
    "CTUSBDU
    7JFX$POUSPMMFS
    6*7JFX$POUSPMMFS

    View Slide

  21. Copyright © 2017 eureka, Inc. All rights reserved.
    21
    Redux with ReSwift
    3F4XJGU3F4XJGUΛ༻͍ͨ3FEVY-JLFͳΞʔΩςΫνϟͰ࣮ݧ
    ୯Ұํ޲ͷॲཧϑϩʔ
    ঢ়ଶͷදݱɾ؅ཧɾมߋͷ੹຿͕෼͚ΒΕ͍ͯΔ
    ঢ়ଶΛҰͭʹू໿
    ίϯϙʔωϯτΛ֦ு͠΍͍͢࡞Γ
    https://github.com/ReSwift/ReSwift

    View Slide

  22. https://github.com/ReSwift/ReSwift

    View Slide

  23. 6TFS4FBSDI"DUJPO
    6TFS4FBSDI
    7JFX$POUSPMMFS
    "QQ4UPSF
    "QQ4UBUF
    6TFS4FBSDI4UBUF
    "QQ3FEVDFS 6TFS4FBSDI3FEVDFS
    .JEEMFXBSF

    View Slide

  24. 6TFS4FBSDI"DUJPO
    6TFS4FBSDI
    7JFX$POUSPMMFS
    "QQ4UPSF
    "QQ4UBUF
    6TFS4FBSDI4UBUF
    "QQ3FEVDFS 6TFS4FBSDI3FEVDFS
    .JEEMFXBSF

    View Slide

  25. 6TFS4FBSDI"DUJPO
    6TFS4FBSDI
    7JFX$POUSPMMFS
    "QQ4UPSF
    "QQ4UBUF
    6TFS4FBSDI4UBUF
    "QQ3FEVDFS 6TFS4FBSDI3FEVDFS
    .JEEMFXBSF

    View Slide

  26. 6TFS4FBSDI"DUJPO
    6TFS4FBSDI
    7JFX$POUSPMMFS
    "QQ4UPSF
    "QQ4UBUF
    6TFS4FBSDI4UBUF
    "QQ3FEVDFS 6TFS4FBSDI3FEVDFS
    .JEEMFXBSF

    View Slide

  27. 6TFS4FBSDI"DUJPO
    6TFS4FBSDI
    7JFX$POUSPMMFS
    "QQ4UPSF
    "QQ4UBUF
    6TFS4FBSDI4UBUF
    "QQ3FEVDFS 6TFS4FBSDI3FEVDFS
    .JEEMFXBSF

    View Slide

  28. Copyright © 2017 eureka, Inc. All rights reserved.
    28
    ReSwift࣮૷
    ࣮ࡍͷίʔυʹ͍ͭͯ͸࣌ؒత౎߹্ׂѪ͠·͢
    ޙ΄Ͳ4QFBLFS%FDLʹσΟϨΫλʔζΧοτ൛ͱͯ͠ࢿྉΛެ։͠·͢ͷ
    Ͱɺ͝ࢀߟʹ͍ͯͩ͘͠͞

    View Slide

  29. Copyright © 2017 eureka, Inc. All rights reserved.
    29
    ReSwiftΛ༻͍ͨReduxͷӡ༻
    ॲཧΛ୯Ұํ޲ʹ͢Δ͜ͱʹΑͬͯɺॲཧϑϩʔΛ௥͍΍͘͢ͳͬͨ
    ར༻ଆ͸ɺػೳ௥Ճ࣌ʹؾʹ͢΂͖ࣄ͕ݮͬͨ
    Ҏલ͸͋ΒΏΔঢ়ଶΛ͋ΒΏΔॴͰ؅ཧ͍ͯͨ͠
    "DUJPO 4UBUF 3FEVDFSͱ੹຿͕෼͚ΒΕ͍ͯΔҝɺ࣮૷ऀؒͷ࢓༷ͷζ
    Ϩ͕ܰݮ͞Εͨ

    View Slide

  30. Copyright © 2017 eureka, Inc. All rights reserved.
    ϢʔβͷϨεϙϯεΛ࠷దԽ &
    ಡΈࠐΈͷߴ଎Խ

    View Slide

  31. Copyright © 2017 eureka, Inc. All rights reserved.
    31
    ϢʔβϨεϙϯεͷ࠷దԽ
    ͕͢͞ը໘ͰϦΫΤετͨ͠Ϣʔβ৘ใ͸͋ΒΏΔ৘ใΛؚΜͰ͍ͨ
    ֤ը໘Ͱ࢖͏ҝͷϢʔβͷεςʔτͳͲ
    Ϣʔβ৘ใΛੜ੒͢Δҝͷ༨ܭͳෛՙ͕αʔόαΠυʹ
    NTd

    View Slide

  32. Copyright © 2017 eureka, Inc. All rights reserved.
    32
    ϢʔβϨεϙϯεͷ࠷దԽ
    ͕͢͞ը໘ͳͲɺ(SJE6*্Ͱදࣔ͢ΔϢʔβ৘ใʹඞཁ࠷௿ݶͳϨεϙϯ
    εΛఆٛ
    ϢʔβϨεϙϯεΛ൒෼ʹ
    εϐʔυվળ
    NTNT

    View Slide

  33. Copyright © 2017 eureka, Inc. All rights reserved.
    33
    Ϣʔβ௥ՃಡΈࠐΈͷ࠷దԽ
    Ұ౓ʹԿ݅ϢʔβΛऔΓࠐΉ͔ɺϢʔβͷૢ࡞Λͳ
    Δ΂્͘֐͠ͳ͍MJNJU஋Λࢦఆ͍ͨ͠ ӈ͸मਖ਼લ

    MJNJU஋Λ୹͗͢Δͱ౎౓ಡΈࠐΈ͕ൃੜ͠ɺ௕͗͢
    ΔͱϨΠΞ΢τߋ৽ʹӨڹ͢Δ
    ࠓͷॴ݅Λऔಘ͢Δͷ͕ྑͦ͞͏
    ※ Ϣʔβը૾͸σϞ༻ʹ༻ҙͨ͠΋ͷʹͳΓ·͢

    View Slide

  34. Copyright © 2017 eureka, Inc. All rights reserved.
    34
    Ϣʔβ௥ՃಡΈࠐΈͷ࠷దԽ
    ௥ՃಡΈࠐΈͷऔಘλΠϛϯά΋มߋ
    ࠓ·Ͱ͸ϖʔδ෼खલ͔ΒϦΫΤετϢʔβΛྲྀ͠ಡΈ͍ͯ͠Δ৔߹
    ʹҾ͔͔ͬΓ͕͋ͬͨ
    dϖʔδखલ͙Β͍͔ΒϦΫΤετ͢Δͷ͕Αͦ͞͏ʁ

    View Slide

  35. Copyright © 2017 eureka, Inc. All rights reserved.
    35
    ը૾ಡΈࠐΈߴ଎Խ
    ը૾ͷಡΈࠐΈ଎౓ͷվળ
    ը૾ͷಡΈࠐΈλΠϛϯάͷݟ௚͠

    View Slide

  36. Copyright © 2017 eureka, Inc. All rights reserved.
    36
    ը૾ಡΈࠐΈߴ଎Խ with Nuke
    LFBO/VLFͷಋೖ
    Ұ௨Γͷػೳ͸׬උ
    ,JOHpTIFS౳ͱൺ΂ͯ΋ߴ଎
    $BDIF΍3FRVFTUपΓͷΧελϚΠζ͕͠΍͍͢
    ※ https://qiita.com/H_Crane/items/422811dfc18ae919f8a4

    View Slide

  37. Copyright © 2017 eureka, Inc. All rights reserved.
    37
    ը૾ಡΈࠐΈߴ଎Խ with Nuke
    https://github.com/kean/Image-Frameworks-Benchmark

    View Slide

  38. Copyright © 2017 eureka, Inc. All rights reserved.
    38
    ը૾ಡΈࠐΈߴ଎Խ with Nuke
    https://github.com/kean/Image-Frameworks-Benchmark

    View Slide

  39. Copyright © 2017 eureka, Inc. All rights reserved.
    39
    ը૾ಡΈࠐΈߴ଎Խ with Nuke
    Nuke.loadImage(
    with: ImageRequest(url: url),
    options: ImageLoadingOptions(
    transition: .fadeIn(duration: 0.33)
    ),
    into: imageView)
    // That’s it!

    View Slide

  40. Copyright © 2017 eureka, Inc. All rights reserved.
    40
    Nuke with Prefetch API
    J04͔Β6*$PMMFDUJPO7JFX%BUB4PVSDF1SFGFUDIJOH͕࢖͑Δ
    1SFGFUDIJOH/VLF*NBHF1SFIFBUFS
    XJMM%JTQMBZGPS*UFN"UͰ͍ͯͨ͠ը૾ߋ৽ΛDFMM'PS*UFN"UͰߦ͏Α͏ʹ
    มߋ
    J04͔Βݺ͹ΕΔλΠϛϯά͕มΘͬͨ ͱͷ͜ͱ͚ͩͲ΋ɾɾʁ

    View Slide

  41. Copyright © 2017 eureka, Inc. All rights reserved.
    41
    Prefetching + Nuke.ImagePreheater
    extension UserSearchViewController: UICollectionViewDataSourcePrefetching {
    fileprivate let preheater: Nuke.ImagePreheater
    func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths:
    [IndexPath]) {
    DispatchQueue(label: "scene.discovery.vc.prefetch").async { [weak self] in
    let requests: [Nuke.ImageRequest] = indexPaths.map({..})
    self?.preheater.startPreheating(with: requests)
    }
    }
    func collectionView(_ collectionView: UICollectionView,
    cancelPrefetchingForItemsAt indexPaths: [IndexPath]) {
    preheater.stopPreheating()
    }
    }

    View Slide

  42. Copyright © 2017 eureka, Inc. All rights reserved.
    42
    Prefetching + Nuke.ImagePreheater
    extension UserSearchViewController: UICollectionViewDataSourcePrefetching {
    fileprivate let preheater: Nuke.ImagePreheater
    func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths:
    [IndexPath]) {
    DispatchQueue(label: "scene.discovery.vc.prefetch").async { [weak self] in
    let requests: [Nuke.ImageRequest] = indexPaths.map({..})
    self?.preheater.startPreheating(with: requests)
    }
    }
    func collectionView(_ collectionView: UICollectionView,
    cancelPrefetchingForItemsAt indexPaths: [IndexPath]) {
    preheater.stopPreheating()
    }
    }

    View Slide

  43. Copyright © 2017 eureka, Inc. All rights reserved.
    43
    Prefetching + Nuke.ImagePreheater
    extension UserSearchViewController: UICollectionViewDataSourcePrefetching {
    fileprivate let preheater: Nuke.ImagePreheater
    func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths:
    [IndexPath]) {
    DispatchQueue(label: "scene.discovery.vc.prefetch").async { [weak self] in
    let requests: [Nuke.ImageRequest] = indexPaths.map({..})
    self?.preheater.startPreheating(with: requests)
    }
    }
    func collectionView(_ collectionView: UICollectionView,
    cancelPrefetchingForItemsAt indexPaths: [IndexPath]) {
    preheater.stopPreheating()
    }
    }

    View Slide

  44. Copyright © 2017 eureka, Inc. All rights reserved.
    44
    ஫ҙ఺
    1SFGFUDI"1*
    දࣔ༧ఆͷ͢΂ͯͷ*OEFY1BUI͕౉͞ΕΔ༁Ͱ͸ͳ͍
    DFMM'PS*UFN"U
    1BJSTͷ؀ڥͰ͸΄΅XJMM%JTQMBZGPS*UFN"Uͱಉ͡λΠϛϯάͩͬͨ
    Կ͔͠Βͷ޻෉͕ඞཁ͔΋

    View Slide

  45. Copyright © 2017 eureka, Inc. All rights reserved.
    45
    ϢʔβͷϨεϙϯε࠷దԽ & ը૾ಡΈࠐΈߴ଎Խ
    ࠓ·Ͱͷഒऔಘεϐʔυ͕ૣ͍ҝɺϦϑϨογϡɺ௥ՃಡΈࠐΈ࣌ͷετ
    ϨεΛܰݮ
    ը૾ΛεΫϩʔϧ࣌ʹ͙֬͢ೝͰ͖ΔͨΊɺϢʔβ͕͙͢ʹΞΫγϣϯͰ
    ͖ΔΑ͏ʹͳͬͨ

    View Slide

  46. Copyright © 2017 eureka, Inc. All rights reserved.
    ໨ࢦͤ60fps

    View Slide

  47. 60fpsͰψϧψϧମݧΛఏڙ͍ͨ͠

    View Slide

  48. View Slide

  49. Copyright © 2017 eureka, Inc. All rights reserved.
    49
    AutoLayout͸଎߈Ͱ௚͞ͳ͚Ε͹ͳΒͳ͍
    ͔ͳΓޮՌ͕͋ͬͨ ମײ

    ͳͥ΍ͬͯͳ͔ͬͨ

    View Slide

  50. Copyright © 2017 eureka, Inc. All rights reserved.
    50
    Fix AutoLayout tips
    ·ͣ͸ͳ͓͢΂͖$POTUSBJOUΛ൑ผ͢Δ
    /4-BZPVU$POTUSBJOUJEFOUJpFS
    7JFX%FCVHHFS 3FWFBM

    View Slide

  51. Copyright © 2017 eureka, Inc. All rights reserved.
    51
    Fix AutoLayout tips - NSLayoutConstraint.identifier
    /4-BZPVU$POTUSBJOUʹ͸JEFOUJpFS͕ઃఆՄೳ
    ίʔυ্Ͱ΋ઃఆՄ

    View Slide

  52. Copyright © 2017 eureka, Inc. All rights reserved.
    52
    Fix AutoLayout tips - NSLayoutConstraint.identifier

    View Slide

  53. Copyright © 2017 eureka, Inc. All rights reserved.
    53
    Fix AutoLayout tips - View Debugger

    View Slide

  54. Copyright © 2017 eureka, Inc. All rights reserved.
    54
    Fix AutoLayout tips - Reveal
    3FWFBMͰ΋ಉ༷ʹ/4-BZPVU$POTUSBJOU
    ΍7JFXΛΞυϨεͰݕࡧՄೳ
    յΕ੍͍ͯͨ໿ΛϚʔΫͯ͘͠ΕΔҝݟ΍
    ͍͢

    View Slide

  55. AutoLayout͕յΕͨ৔߹͸
    ଎߈Ͱ௚͠·͠ΐ͏

    View Slide

  56. Copyright © 2017 eureka, Inc. All rights reserved.
    56
    Color Blended Layers
    7JFX -BZFS
    ΛॏͶͯඳը͍ͯ͠Δ෦෼
    ॏͳΓ߹͏ϨΠϠʔΛൺֱ͠࠷ऴతͳग़ྗ஋Λܭࢉ
    ͢ΔҝɺඳըύϑΥʔϚϯεʹӨڹ͢Δ

    View Slide

  57. Copyright © 2017 eureka, Inc. All rights reserved.
    57
    Color Blended Layers ֬ೝํ๏
    4JNVMBUPSͷ৔߹
    .FOV$PMPS#MFOEFE-BZFSTʹνΣοΫ

    View Slide

  58. Copyright © 2017 eureka, Inc. All rights reserved.
    58
    Color Blended Layers ֬ೝ
    ࣮ػͷ৔߹ 9DPEF

    9DPEF%FCVH7JFX%FCVHHJOH3FOEFSJOH$PMPS#MFOEFE
    -BZFSTʹνΣοΫ

    View Slide

  59. Copyright © 2017 eureka, Inc. All rights reserved.
    59
    Color Blended Layers ରࡦ - UIImageView
    Ͱ͖ΔݶΓCBDLHSPVOE$PMPSΛࢦఆ͢Δ
    ಁաը૾ΛͳΔ΂͘࢖Θͳ͍
    ະಁաͷΑ͏ͳը૾Ͱ΋BMQIB஋ؚ͕·Ε͍ͯΔ
    ৔߹͕͋ΔͨΊ஫ҙ

    View Slide

  60. Copyright © 2017 eureka, Inc. All rights reserved.
    60
    Color Blended Layers ରࡦ - UILabel
    Ͱ͖ΔݶΓCBDLHSPVOE$PMPSΛࢦఆ͢Δ
    DMJQT5P#PVOETΛUSVFʹ
    ೔ຊޠɾதࠃޠͳͲΛදࣔ͢Δ৔߹ɺڪΒ͘TVCMBZFS͕௥Ճ͞Ε͍ͯΔ
    ҝ
    ˞EFTDFOU஋͕ਖ਼͘͠ઃఆ͞Ε͍ͯΔTZTUFN'POUʹݶΔ

    View Slide

  61. Copyright © 2017 eureka, Inc. All rights reserved.
    61
    Color Blended Layers ରࡦ - UILabel
    System Font + clipsToBounds HirakakuProN-W3 + clipsToBounds
    MFBEJOH஋Λແࢹͯ͠DMJQ͍ͯ͠Δ
    https://speakerdeck.com/satoshin21/uifontdescriptor?slide=8
    leading஋ͳͲʹ͍ͭͯ͸ɺҎલpotatotipsͰൃදͨ͠ࢿྉΛ͝ࢀߟʹ͍ͯͩ͘͠͞

    View Slide

  62. Copyright © 2017 eureka, Inc. All rights reserved.
    62
    Offscreen Rendering
    ؙ֯΍ӨΛεΫϦʔϯ্ʹඳը͢ΔࡍɺϨϯμϦϯάલʹલ΋ͬͯ Φϑε
    ΫϦʔϯͰ
    ॲཧΛߦ͏
    ϋʔυ΢ΣΞΞΫηϥϨʔγϣϯ (16
    Λ࢖༻͍ͯ͠ͳ͍ҝύϑΥʔϚ
    ϯε௿ԼͷҰҼͱͳΔ
    SBTUFSJ[F΋͢΂͖λΠϛϯάͱ͢΂͖Ͱͳ͍λΠϛϯά͕͋Δ
    J04Ҏ߱Ͱ͸6**NBHF7JFXͰ࠷దԽ͞Ε͍ͯΔͱ͍͏͕ᷚͩɾɾ

    View Slide

  63. Copyright © 2017 eureka, Inc. All rights reserved.
    63
    Offscreen Rendering - ֬ೝํ๏
    $PMPS#MFOEFE-BZFSTͱಉ͡ํࣜͰ
    0⒎TDSFFO3FOEFSJOHΛ࣮ߦ͍ͯ͠ΔՕॴΛ৭
    ෇͚Ͱ͖Δ

    View Slide

  64. Copyright © 2017 eureka, Inc. All rights reserved.
    64
    Offscreen Rendering - ରࡦ
    ؙ֯༻ͷ.BTL7JFXΛ6**NBHF7JFXͷ্ʹ
    ৐ͤΔํࣜͰ0⒎TDSFFO3FOEFSJOHΛආ͚ͯ
    ͍Δ
    վमલ͔Βߦ͍ͬͯΔҝɺৄࡉ͸ׂѪ ฐࣾͷ
    ϒϩάΛࢀর͍ͯͩ͘͠͞

    https://medium.com/eureka-engineering/iosͷϋΠύϑΥʔϚϯεͳcorner-rounding-strategy-88a43641b554

    View Slide

  65. Copyright © 2017 eureka, Inc. All rights reserved.
    65
    ࠩ෼ߋ৽
    ݱࡏ͸௥ՃಡΈࠐΈɺ1VMMUP3FGSFTI͢Δͨͼʹ
    DPMMFDUJPO7JFXSFMPBE%BUB
    ΛݺΜͰ͍ͨ
    SFMPBE%BUB
    ΛݺͿ͜ͱͰෆඞཁͳWJTJCMF$FMMTͷߋ৽͕࣮ߦ͞ΕΔ

    View Slide

  66. Copyright © 2017 eureka, Inc. All rights reserved.
    66
    ࠩ෼ߋ৽ - Libraries
    *OTUBHSBN*(-JTU,JU
    TFDUJPOϕʔεͷࠩ෼ൺֱ
    3Y4XJGU$PNNVOJUZ3Y%BUB4PVSDFT
    KqJOUFS%XJ⒎U
    NVVLJJ%BUB4PVSDFT

    View Slide

  67. Copyright © 2017 eureka, Inc. All rights reserved.
    67
    muukii/DataSources
    NVVLJJ%BUB4PVSDFT
    *(-JTU,JUͳͲͷࠩ෼நग़ΞϧΰϦζϜΛࢀߟʹ࡞ΒΕ͍ͯΔ
    λΠϓηʔϑ
    ࠩ෼நग़ʹಛԽͨ͠γϯϓϧͳ࢓૊Έطଘͷ࢓૊Έͱ਌࿨ੑ͕ߴ͍
    ฐࣾϝϯόʔ NVVLJJ
    ͕࡞͍ͬͯΔҝɺ࣭໰͕͋ͬͨΒ͙͢ฉ͚Δ

    View Slide

  68. Copyright © 2017 eureka, Inc. All rights reserved.
    68
    muukii/DataSources - ModelΛఆٛ
    enum Item {
    case user(User)
    case banner(Banner)
    case feature(Feature) // Ϩίϝϯυ࿮ͷΑ͏ͳ΋ͷ
    }

    View Slide

  69. Copyright © 2017 eureka, Inc. All rights reserved.
    69
    muukii/DataSources - ModelΛఆٛ
    import DataSources
    extension Item: DataSources.Diffable {
    typealias Identifier = String
    var diffIdentifier: String {
    switch self {
    case .user(let user): return user.diffIdentifier
    case .banner(let banner): return banner.diffIdentifier
    case .feature(let feature): return feature.diffIdentifier
    }
    }
    }

    View Slide

  70. Copyright © 2017 eureka, Inc. All rights reserved.
    70
    muukii/DataSources - ModelΛఆٛ
    import DataSources
    extension Item: DataSources.Diffable {
    typealias Identifier = String
    var diffIdentifier: String {
    switch self {
    case .user(let user): return user.diffIdentifier
    case .banner(let banner): return banner.diffIdentifier
    case .feature(let feature): return feature.diffIdentifier
    }
    }
    }

    View Slide

  71. Copyright © 2017 eureka, Inc. All rights reserved.
    71
    muukii/DataSources - ModelΛఆٛ
    import DataSources
    extension Item: DataSources.Diffable {
    typealias Identifier = String
    var diffIdentifier: String {
    switch self {
    case .user(let user): return user.diffIdentifier
    case .banner(let banner): return banner.diffIdentifier
    case .feature(let feature): return feature.diffIdentifier
    }
    }
    }

    View Slide

  72. Copyright © 2017 eureka, Inc. All rights reserved.
    72
    muukii/DataSources - SectionControllerΛఆٛ
    final class UserSearchViewController: UIViewController, StoreSubscriber {
    fileprivate lazy var sectionController:
    DataSources.SectionDataController = .init(
    adapter: .init(collectionView: self.collectionView),
    displayingSection: 0,
    isEqual: { a, b in a.diffIdentifier == b.diffIdentifier }
    )
    }

    View Slide

  73. Copyright © 2017 eureka, Inc. All rights reserved.
    73
    muukii/DataSources - SectionControllerΛఆٛ
    final class UserSearchViewController: UIViewController, StoreSubscriber {
    fileprivate lazy var sectionController:
    DataSources.SectionDataController = .init(
    adapter: .init(collectionView: self.collectionView),
    displayingSection: 0,
    isEqual: { a, b in a.diffIdentifier == b.diffIdentifier }
    )
    }

    View Slide

  74. Copyright © 2017 eureka, Inc. All rights reserved.
    74
    muukii/DataSources - SectionControllerΛఆٛ
    final class UserSearchViewController: UIViewController, StoreSubscriber {
    fileprivate lazy var sectionController:
    DataSources.SectionDataController = .init(
    adapter: .init(collectionView: self.collectionView),
    displayingSection: 0,
    isEqual: { a, b in a.diffIdentifier == b.diffIdentifier }
    )
    }

    View Slide

  75. Copyright © 2017 eureka, Inc. All rights reserved.
    75
    muukii/DataSources - SectionControllerΛఆٛ
    final class UserSearchViewController: UIViewController, StoreSubscriber {
    func newState(state: State) {
    switch state.loadingState {
    case .loaded(let items):
    self.sectionController.update(
    items: items,
    updateMode: .partial(animated: true),
    completion: {
    Log.info("updated")
    })
    }
    }
    }

    View Slide

  76. Copyright © 2017 eureka, Inc. All rights reserved.
    76
    muukii/DataSources - SectionControllerΛఆٛ
    final class UserSearchViewController: UIViewController, StoreSubscriber {
    func newState(state: State) {
    switch state.loadingState {
    case .loaded(let items):
    self.sectionController.update(
    items: items,
    updateMode: .partial(animated: true),
    completion: {
    Log.info("updated")
    })
    }
    }
    }

    View Slide

  77. Copyright © 2017 eureka, Inc. All rights reserved.
    77
    muukii/DataSources - SectionControllerΛఆٛ
    final class UserSearchViewController: UIViewController, StoreSubscriber {
    func newState(state: State) {
    switch state.loadingState {
    case .loaded(let items):
    self.sectionController.update(
    items: items,
    updateMode: .partial(animated: true),
    completion: {
    Log.info("updated")
    })
    }
    }
    }

    View Slide

  78. 60fpsʹ͚ۙͮͨͷ͔ʁ

    View Slide

  79. ߋ৽લ ߋ৽ޙ
    iPhone 5(MD297J/A) iOS 10.3.3
    ※ Ϣʔβը૾͸σϞ༻ʹ༻ҙͨ͠΋ͷʹͳΓ·͢

    View Slide

  80. ߋ৽લ ߋ৽ޙ
    36fps
    60fps
    55fps
    iPhone 5(MD297J/A) iOS 10.3.3
    ※ Ϣʔβը૾͸σϞ༻ʹ༻ҙͨ͠΋ͷʹͳΓ·͢

    View Slide

  81. Copyright © 2017 eureka, Inc. All rights reserved.
    ·ͱΊ

    View Slide

  82. Copyright © 2017 eureka, Inc. All rights reserved.
    82
    վળ݁Ռ
    ਓؒʹ͸ཧղ͕೉͔ͬͨ͠ॲཧϑϩʔΛ3FEVYΛಋೖ͢Δ͜ͱͰΘ͔Γ΍
    ͘͢ఆٛ͢Δ͜ͱ͕Ͱ͖ͨ
    ৮͍ͬͯͯ৺஍͍͍6*69Λఏڙ͢Δϕʔε͕Ͱ͖ͨ
    GQTΛҰͭͷࢦඪͱ͢Δ͜ͱͰɺ6*69޲্ΛఆྔԽ͢Δ͜ͱ͕Ͱ͖ͨ

    View Slide

  83. Copyright © 2017 eureka, Inc. All rights reserved.
    83
    օ͞Μʹ͓ئ͍
    Τ΢ϨΧϒʔεΛ༻ҙ͍ͯ͠·͢ʂ
    ΋͠ɺύϑΥʔϚϯενϡʔχϯάʹؔͯ͠ڵຯ͕͋Δํɺʮ͜ΕΛվળ
    ͨ͠ΒύϑΥʔϚϯε޲্ͨ͠ΑʂʯͳͲͷϊ΢ϋ΢͕͋ΔํͳͲ͍Βͬ
    ͠Ό͍·ͨ͠Βɺੋඇͱ΋৘ใަ׵͠·͠ΐ͏

    View Slide

  84. Thank you
    IUUQTXXXOBTBHPWNJTTJPO@QBHFT/11OFXTFBSUIBUOJHIUIUNM

    View Slide