Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
レガシーなアプリケーションの 60fps化を目指す為にやっていること
Search
satoshin21
August 31, 2018
Programming
4.2k
12
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
レガシーなアプリケーションの 60fps化を目指す為にやっていること
iOSDC2018
8/31 17:40
@早稲田大学理工学部 西早稲田キャンパス 63号館
satoshin21
August 31, 2018
More Decks by satoshin21
See All by satoshin21
少数精鋭で戦うための技術的改善について
satoshin21
3
1.5k
GTXiLibで小さく始めるAccessibility Testing
satoshin21
0
5.5k
iPhoneのカメラで写真撮影から現像までの技術を紐解く
satoshin21
5
3.9k
try! swift-sh
satoshin21
2
1.1k
Reduxを取り入れて開発はpairs開発はどう変わったか
satoshin21
0
420
Introducing CodeLayout with Tips
satoshin21
6
1.7k
World of No Interface Builder
satoshin21
0
2.1k
What I've done to attend WWDC
satoshin21
0
170
Swift Package Manager V4でAlfred Workflowを作ろう
satoshin21
0
330
Other Decks in Programming
See All in Programming
Agents on Rails - Rails at Scale 2026
irinanazarova
0
290
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
140
Are APIs Still Relevant in the AI Era?
soyuka
0
350
Vue Fes Japan 2026 タイムテーブル徹底解説
448jp
1
560
Ghostty + Neovimで作る 透明でカッコ良い開発環境
j341nono
0
140
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
18
19k
JPUG勉強会 OSSデータベースの内部構造を理解しよう(第2回)
oga5
0
280
20260914 AIエージェント時代のPlatform Engineering LLM基盤とプロダクトの責務境界線
kanfab1
7
2.3k
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
9k
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
360
Java 27新機能 / Java 27 new features
kishida
2
180
FreeBSDでZabbixを動かす
kenkino
0
340
Featured
See All Featured
Deep Space Network (abreviated)
tonyrice
0
330
Git: the NoSQL Database
bkeepers
PRO
432
67k
Why Our Code Smells
bkeepers
PRO
340
58k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.9k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Making the Leap to Tech Lead
cromwellryan
135
10k
For a Future-Friendly Web
brad_frost
183
10k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
470
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Unsuck your backbone
ammeep
672
58k
Transcript
Copyright © 2017 eureka, Inc. All rights reserved. What we’ve
done to get High Performance in our Legacy Application ϨΨγʔͳΞϓϦέʔγϣϯͷ 60fpsԽΛࢦ͢ҝʹ͍ͬͯΔ͜ͱ
Copyright © 2017 eureka, Inc. All rights reserved. 2 Introduce
FVSFLB *OD 1BJSTJ04"QQMJDBUJPO&OHJOFFS ྑΧϝϥϚϯͬͯ·͢ඃࣸମʹծ͑ͯΔͷͰࣸਅࡱΒΕͯԼ͍͞ @satoshin21
Copyright © 2017 eureka, Inc. All rights reserved. 3 Agenda
1BJSTͷհͱJ04νʔϜͷ՝ ॲཧϑϩʔΛ͍͍͢ΞʔΩςΫνϟͷಋೖ Ϩεϙϯεͷ࠷దԽಡΈࠐΈߴԽ ࢦͤGQT$PMMFDUJPO7JFXνϡʔχϯά Ռͨͯ͠GQTͰվળͨ͠ͷ͔ʁ
Copyright © 2017 eureka, Inc. All rights reserved. Pairsͷհ &
iOSνʔϜͷ՝
None
Copyright © 2017 eureka, Inc. All rights reserved. 6 ྺ࢙Λ࣋ͭPairs
αʔϏε։݄࢝ ݄ʹ1BJSTGPSJ04W͕ఏڙ։࢝ ݄ʹϑϧεΫϥον
Copyright © 2017 eureka, Inc. All rights reserved. 7 2018ݱࡏͷ՝
0CKFDUJWF$͕ࠜװΛ୲͍ͬͯΔ෦͕͋Δҝɺ4XJGUͷϙςϯγϟϧΛ࠷ େݶੜ͔ͤͳ͍ ػೳՃɾվળεϐʔυ্͕͕͍ͬͯΔ͕ɺϓϩμΫτ͕ͦͷεϐʔυʹ ͍͚͍ͭͯͳ͍ ٕज़ෛ࠴͕ஷ·ΓɺϓϩμΫτͷύϑΥʔϚϯεʹӨڹ͕ग़࢝Ί͍ͯΔ ͔Β࡞Γ͍͕ͨ͠ɺίετ͕ߴ͍
Ͳ͏ʹ͔վળ͍ͨ͠
͍͖ͳΓશͯΛ࡞Γม͑ΔͷͰͳ͘ શମ࠷దԽʹ͚ͯҰาͮͭਐΉ
Copyright © 2017 eureka, Inc. All rights reserved. 10 શମ࠷దͱ෦࠷ద
શମ࠷దͷಓҰͭͰͳ͍ ෦తͳ࠷దԽΛߦ͍ɺͦΕΛϓϩμΫτશମʹల։͍ͯ͘͠ શମ࠷దΛݟਾ͑ͨ෦࠷దΛߦ͏
෦࠷దΛ͢ΔͷͰ͋Εɾɾ
Ϣʔβ͕ޮՌΛ࣮ײ͍͢͠ & ཏతͳػೳ͕ଘࡏ͢Δ
ϢʔβΛ͕͢͞ը໘
Copyright © 2017 eureka, Inc. All rights reserved. 14 ͕͢͞ը໘ʹܾΊͨཧ༝
ϩάΠϯޙɺҰ൪࠷ॳʹදࣔ͞ΕΔը໘ Ϣʔβʹ࠷ར༻͞ΕΔը໘ͷҰͭ ϓϩμΫτͰԣల։Մೳͳ༷ʑͳػೳ $PMMFDUJPO7JFX ϦϩʔυɺՃಡΈࠐΈɺ༷ʑͳσʔλΛҰཡදࣔ
Copyright © 2017 eureka, Inc. All rights reserved. 15 ͕͢͞ը໘ͷ՝
൚༻ԽͷҝͷଟܧঝͰॲཧ͕͍ʹ͍͘ Ϣʔβͷσʔλྔ͕ଟ͍ҝɺϩʔυʹ͕͔͔࣌ؒ Δ εΫϩʔϧ࣌ʹΨλͭ͘ ฏۉdGQT J1IPOFJ04Ͱܭଌ ※ Ϣʔβը૾σϞ༻ʹ༻ҙͨ͠ͷʹͳΓ·͢
Copyright © 2017 eureka, Inc. All rights reserved. 16 ΤϨΧ
ͷ iOS/Android/Web Engineer 6*69ʹ߆Γ͕ڧ͍ 6*ψϧψϧܯ͕ৗற *OTUBHSBN5JOEFSͳͲΠέͯΔ6*69Λࢦ͢
Copyright © 2017 eureka, Inc. All rights reserved. 17 ෦࠷దͷඪ
ॲཧϑϩʔΛ͍͍͢ΞʔΩςΫνϟͷಋೖ ϢʔβͷϨεϙϯεΛ࠷దԽಡΈࠐΈͷߴԽ ࢦͤGQT
Copyright © 2017 eureka, Inc. All rights reserved. ॲཧϑϩʔΛ͍͍͢ ΞʔΩςΫνϟͷಋೖ
Copyright © 2017 eureka, Inc. All rights reserved. 19 ݱࡏͷ͕͢͞ը໘
'BU7JFX$POUSPMMFS ͕͢͞ը໘Ͱͭͷ7JFX$POUSPMMFSΛܧঝ͢Δଟߏ
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
Copyright © 2017 eureka, Inc. All rights reserved. 21 Redux
with ReSwift 3F4XJGU3F4XJGUΛ༻͍ͨ3FEVY-JLFͳΞʔΩςΫνϟͰ࣮ݧ ୯Ұํͷॲཧϑϩʔ ঢ়ଶͷදݱɾཧɾมߋͷ͕͚ΒΕ͍ͯΔ ঢ়ଶΛҰͭʹू ίϯϙʔωϯτΛ֦ு͍͢͠࡞Γ https://github.com/ReSwift/ReSwift
https://github.com/ReSwift/ReSwift
6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF
6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF
6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF
6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF
6TFS4FBSDI"DUJPO 6TFS4FBSDI 7JFX$POUSPMMFS "QQ4UPSF "QQ4UBUF 6TFS4FBSDI4UBUF "QQ3FEVDFS 6TFS4FBSDI3FEVDFS .JEEMFXBSF
Copyright © 2017 eureka, Inc. All rights reserved. 28 ReSwift࣮
࣮ࡍͷίʔυʹ͍ͭͯ࣌ؒత߹্ׂѪ͠·͢ ޙ΄Ͳ4QFBLFS%FDLʹσΟϨΫλʔζΧοτ൛ͱͯ͠ࢿྉΛެ։͠·͢ͷ Ͱɺ͝ࢀߟʹ͍ͯͩ͘͠͞
Copyright © 2017 eureka, Inc. All rights reserved. 29 ReSwiftΛ༻͍ͨReduxͷӡ༻
ॲཧΛ୯Ұํʹ͢Δ͜ͱʹΑͬͯɺॲཧϑϩʔΛ͍͘͢ͳͬͨ ར༻ଆɺػೳՃ࣌ʹؾʹ͖͢ࣄ͕ݮͬͨ Ҏલ͋ΒΏΔঢ়ଶΛ͋ΒΏΔॴͰཧ͍ͯͨ͠ "DUJPO 4UBUF 3FEVDFSͱ͕͚ΒΕ͍ͯΔҝɺ࣮ऀؒͷ༷ͷζ Ϩ͕ܰݮ͞Εͨ
Copyright © 2017 eureka, Inc. All rights reserved. ϢʔβͷϨεϙϯεΛ࠷దԽ &
ಡΈࠐΈͷߴԽ
Copyright © 2017 eureka, Inc. All rights reserved. 31 ϢʔβϨεϙϯεͷ࠷దԽ
͕͢͞ը໘ͰϦΫΤετͨ͠Ϣʔβใ͋ΒΏΔใΛؚΜͰ͍ͨ ֤ը໘Ͱ͏ҝͷϢʔβͷεςʔτͳͲ ϢʔβใΛੜ͢Δҝͷ༨ܭͳෛՙ͕αʔόαΠυʹ NTd
Copyright © 2017 eureka, Inc. All rights reserved. 32 ϢʔβϨεϙϯεͷ࠷దԽ
͕͢͞ը໘ͳͲɺ(SJE6*্Ͱදࣔ͢ΔϢʔβใʹඞཁ࠷ݶͳϨεϙϯ εΛఆٛ ϢʔβϨεϙϯεΛʹ εϐʔυվળ NTNT
Copyright © 2017 eureka, Inc. All rights reserved. 33 ϢʔβՃಡΈࠐΈͷ࠷దԽ
ҰʹԿ݅ϢʔβΛऔΓࠐΉ͔ɺϢʔβͷૢ࡞Λͳ Δ્͘͠ͳ͍MJNJUΛࢦఆ͍ͨ͠ ӈमਖ਼લ MJNJUΛ͗͢ΔͱಡΈࠐΈ͕ൃੜ͠ɺ͗͢ ΔͱϨΠΞτߋ৽ʹӨڹ͢Δ ࠓͷॴ݅Λऔಘ͢Δͷ͕ྑͦ͞͏ ※ Ϣʔβը૾σϞ༻ʹ༻ҙͨ͠ͷʹͳΓ·͢
Copyright © 2017 eureka, Inc. All rights reserved. 34 ϢʔβՃಡΈࠐΈͷ࠷దԽ
ՃಡΈࠐΈͷऔಘλΠϛϯάมߋ ࠓ·Ͱϖʔδखલ͔ΒϦΫΤετϢʔβΛྲྀ͠ಡΈ͍ͯ͠Δ߹ ʹҾ͔͔ͬΓ͕͋ͬͨ dϖʔδखલ͙Β͍͔ΒϦΫΤετ͢Δͷ͕Αͦ͞͏ʁ
Copyright © 2017 eureka, Inc. All rights reserved. 35 ը૾ಡΈࠐΈߴԽ
ը૾ͷಡΈࠐΈͷվળ ը૾ͷಡΈࠐΈλΠϛϯάͷݟ͠
Copyright © 2017 eureka, Inc. All rights reserved. 36 ը૾ಡΈࠐΈߴԽ
with Nuke LFBO/VLFͷಋೖ Ұ௨Γͷػೳඋ ,JOHpTIFSͱൺͯߴ $BDIF3FRVFTUपΓͷΧελϚΠζ͕͍͢͠ ※ https://qiita.com/H_Crane/items/422811dfc18ae919f8a4
Copyright © 2017 eureka, Inc. All rights reserved. 37 ը૾ಡΈࠐΈߴԽ
with Nuke https://github.com/kean/Image-Frameworks-Benchmark
Copyright © 2017 eureka, Inc. All rights reserved. 38 ը૾ಡΈࠐΈߴԽ
with Nuke https://github.com/kean/Image-Frameworks-Benchmark
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!
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͔ΒݺΕΔλΠϛϯά͕มΘͬͨ ͱͷ͜ͱ͚ͩͲɾɾʁ
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() } }
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() } }
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() } }
Copyright © 2017 eureka, Inc. All rights reserved. 44 ҙ
1SFGFUDI"1* දࣔ༧ఆͷͯ͢ͷ*OEFY1BUI͕͞ΕΔ༁Ͱͳ͍ DFMM'PS*UFN"U 1BJSTͷڥͰ΄΅XJMM%JTQMBZGPS*UFN"Uͱಉ͡λΠϛϯάͩͬͨ Կ͔͠Βͷ͕ඞཁ͔
Copyright © 2017 eureka, Inc. All rights reserved. 45 ϢʔβͷϨεϙϯε࠷దԽ
& ը૾ಡΈࠐΈߴԽ ࠓ·Ͱͷഒऔಘεϐʔυ͕ૣ͍ҝɺϦϑϨογϡɺՃಡΈࠐΈ࣌ͷετ ϨεΛܰݮ ը૾ΛεΫϩʔϧ࣌ʹ͙֬͢ೝͰ͖ΔͨΊɺϢʔβ͕͙͢ʹΞΫγϣϯͰ ͖ΔΑ͏ʹͳͬͨ
Copyright © 2017 eureka, Inc. All rights reserved. ࢦͤ60fps
60fpsͰψϧψϧମݧΛఏڙ͍ͨ͠
None
Copyright © 2017 eureka, Inc. All rights reserved. 49 AutoLayout߈Ͱ͞ͳ͚ΕͳΒͳ͍
͔ͳΓޮՌ͕͋ͬͨ ମײ ͳͥͬͯͳ͔ͬͨ
Copyright © 2017 eureka, Inc. All rights reserved. 50 Fix
AutoLayout tips ·ͣͳ͓͖͢$POTUSBJOUΛผ͢Δ /4-BZPVU$POTUSBJOUJEFOUJpFS 7JFX%FCVHHFS 3FWFBM
Copyright © 2017 eureka, Inc. All rights reserved. 51 Fix
AutoLayout tips - NSLayoutConstraint.identifier /4-BZPVU$POTUSBJOUʹJEFOUJpFS͕ઃఆՄೳ ίʔυ্ͰઃఆՄ
Copyright © 2017 eureka, Inc. All rights reserved. 52 Fix
AutoLayout tips - NSLayoutConstraint.identifier
Copyright © 2017 eureka, Inc. All rights reserved. 53 Fix
AutoLayout tips - View Debugger
Copyright © 2017 eureka, Inc. All rights reserved. 54 Fix
AutoLayout tips - Reveal 3FWFBMͰಉ༷ʹ/4-BZPVU$POTUSBJOU 7JFXΛΞυϨεͰݕࡧՄೳ յΕ੍͍ͯͨΛϚʔΫͯ͘͠ΕΔҝݟ ͍͢
AutoLayout͕յΕͨ߹ ߈Ͱ͠·͠ΐ͏
Copyright © 2017 eureka, Inc. All rights reserved. 56 Color
Blended Layers 7JFX -BZFS ΛॏͶͯඳը͍ͯ͠Δ෦ ॏͳΓ߹͏ϨΠϠʔΛൺֱ͠࠷ऴతͳग़ྗΛܭࢉ ͢ΔҝɺඳըύϑΥʔϚϯεʹӨڹ͢Δ
Copyright © 2017 eureka, Inc. All rights reserved. 57 Color
Blended Layers ֬ೝํ๏ 4JNVMBUPSͷ߹ .FOV$PMPS#MFOEFE-BZFSTʹνΣοΫ
Copyright © 2017 eureka, Inc. All rights reserved. 58 Color
Blended Layers ֬ೝ ࣮ػͷ߹ 9DPEF 9DPEF%FCVH7JFX%FCVHHJOH3FOEFSJOH$PMPS#MFOEFE -BZFSTʹνΣοΫ
Copyright © 2017 eureka, Inc. All rights reserved. 59 Color
Blended Layers ରࡦ - UIImageView Ͱ͖ΔݶΓCBDLHSPVOE$PMPSΛࢦఆ͢Δ ಁաը૾ΛͳΔ͘Θͳ͍ ະಁաͷΑ͏ͳը૾ͰBMQIBؚ͕·Ε͍ͯΔ ߹͕͋ΔͨΊҙ
Copyright © 2017 eureka, Inc. All rights reserved. 60 Color
Blended Layers ରࡦ - UILabel Ͱ͖ΔݶΓCBDLHSPVOE$PMPSΛࢦఆ͢Δ DMJQT5P#PVOETΛUSVFʹ ຊޠɾதࠃޠͳͲΛදࣔ͢Δ߹ɺڪΒ͘TVCMBZFS͕Ճ͞Ε͍ͯΔ ҝ ˞EFTDFOU͕ਖ਼͘͠ઃఆ͞Ε͍ͯΔTZTUFN'POUʹݶΔ
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Ͱൃදͨ͠ࢿྉΛ͝ࢀߟʹ͍ͯͩ͘͠͞
Copyright © 2017 eureka, Inc. All rights reserved. 62 Offscreen
Rendering ؙ֯ӨΛεΫϦʔϯ্ʹඳը͢ΔࡍɺϨϯμϦϯάલʹલͬͯ Φϑε ΫϦʔϯͰ ॲཧΛߦ͏ ϋʔυΣΞΞΫηϥϨʔγϣϯ (16 Λ༻͍ͯ͠ͳ͍ҝύϑΥʔϚ ϯεԼͷҰҼͱͳΔ SBTUFSJ[F͖͢λΠϛϯάͱ͖͢Ͱͳ͍λΠϛϯά͕͋Δ J04Ҏ߱Ͱ6**NBHF7JFXͰ࠷దԽ͞Ε͍ͯΔͱ͍͏͕ᷚͩɾɾ
Copyright © 2017 eureka, Inc. All rights reserved. 63 Offscreen
Rendering - ֬ೝํ๏ $PMPS#MFOEFE-BZFSTͱಉ͡ํࣜͰ 0⒎TDSFFO3FOEFSJOHΛ࣮ߦ͍ͯ͠ΔՕॴΛ৭ ͚Ͱ͖Δ
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
Copyright © 2017 eureka, Inc. All rights reserved. 65 ࠩߋ৽
ݱࡏՃಡΈࠐΈɺ1VMMUP3FGSFTI͢Δͨͼʹ DPMMFDUJPO7JFXSFMPBE%BUB ΛݺΜͰ͍ͨ SFMPBE%BUB ΛݺͿ͜ͱͰෆඞཁͳWJTJCMF$FMMTͷߋ৽͕࣮ߦ͞ΕΔ
Copyright © 2017 eureka, Inc. All rights reserved. 66 ࠩߋ৽
- Libraries *OTUBHSBN*(-JTU,JU TFDUJPOϕʔεͷࠩൺֱ 3Y4XJGU$PNNVOJUZ3Y%BUB4PVSDFT KqJOUFS%XJ⒎U NVVLJJ%BUB4PVSDFT
Copyright © 2017 eureka, Inc. All rights reserved. 67 muukii/DataSources
NVVLJJ%BUB4PVSDFT *(-JTU,JUͳͲͷࠩநग़ΞϧΰϦζϜΛࢀߟʹ࡞ΒΕ͍ͯΔ λΠϓηʔϑ ࠩநग़ʹಛԽͨ͠γϯϓϧͳΈطଘͷΈͱੑ͕ߴ͍ ฐࣾϝϯόʔ NVVLJJ ͕࡞͍ͬͯΔҝɺ࣭͕͋ͬͨΒ͙͢ฉ͚Δ
Copyright © 2017 eureka, Inc. All rights reserved. 68 muukii/DataSources
- ModelΛఆٛ enum Item { case user(User) case banner(Banner) case feature(Feature) // ϨίϝϯυͷΑ͏ͳͷ }
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 } } }
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 } } }
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 } } }
Copyright © 2017 eureka, Inc. All rights reserved. 72 muukii/DataSources
- SectionControllerΛఆٛ final class UserSearchViewController: UIViewController, StoreSubscriber { fileprivate lazy var sectionController: DataSources.SectionDataController<Item, CollectionViewAdapter> = .init( adapter: .init(collectionView: self.collectionView), displayingSection: 0, isEqual: { a, b in a.diffIdentifier == b.diffIdentifier } ) }
Copyright © 2017 eureka, Inc. All rights reserved. 73 muukii/DataSources
- SectionControllerΛఆٛ final class UserSearchViewController: UIViewController, StoreSubscriber { fileprivate lazy var sectionController: DataSources.SectionDataController<Item, CollectionViewAdapter> = .init( adapter: .init(collectionView: self.collectionView), displayingSection: 0, isEqual: { a, b in a.diffIdentifier == b.diffIdentifier } ) }
Copyright © 2017 eureka, Inc. All rights reserved. 74 muukii/DataSources
- SectionControllerΛఆٛ final class UserSearchViewController: UIViewController, StoreSubscriber { fileprivate lazy var sectionController: DataSources.SectionDataController<Item, CollectionViewAdapter> = .init( adapter: .init(collectionView: self.collectionView), displayingSection: 0, isEqual: { a, b in a.diffIdentifier == b.diffIdentifier } ) }
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") }) } } }
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") }) } } }
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") }) } } }
60fpsʹ͚ۙͮͨͷ͔ʁ
ߋ৽લ ߋ৽ޙ iPhone 5(MD297J/A) iOS 10.3.3 ※ Ϣʔβը૾σϞ༻ʹ༻ҙͨ͠ͷʹͳΓ·͢
ߋ৽લ ߋ৽ޙ 36fps 60fps 55fps iPhone 5(MD297J/A) iOS 10.3.3 ※
Ϣʔβը૾σϞ༻ʹ༻ҙͨ͠ͷʹͳΓ·͢
Copyright © 2017 eureka, Inc. All rights reserved. ·ͱΊ
Copyright © 2017 eureka, Inc. All rights reserved. 82 վળ݁Ռ
ਓؒʹཧղ͕͔ͬͨ͠ॲཧϑϩʔΛ3FEVYΛಋೖ͢Δ͜ͱͰΘ͔Γ ͘͢ఆٛ͢Δ͜ͱ͕Ͱ͖ͨ ৮͍ͬͯͯ৺͍͍6*69Λఏڙ͢Δϕʔε͕Ͱ͖ͨ GQTΛҰͭͷࢦඪͱ͢Δ͜ͱͰɺ6*69্ΛఆྔԽ͢Δ͜ͱ͕Ͱ͖ͨ
Copyright © 2017 eureka, Inc. All rights reserved. 83 օ͞Μʹ͓ئ͍
ΤϨΧϒʔεΛ༻ҙ͍ͯ͠·͢ʂ ͠ɺύϑΥʔϚϯενϡʔχϯάʹؔͯ͠ڵຯ͕͋Δํɺʮ͜ΕΛվળ ͨ͠ΒύϑΥʔϚϯε্ͨ͠ΑʂʯͳͲͷϊϋ͕͋ΔํͳͲ͍Βͬ ͠Ό͍·ͨ͠Βɺੋඇͱใަ͠·͠ΐ͏
Thank you IUUQTXXXOBTBHPWNJTTJPO@QBHFT/11OFXTFBSUIBUOJHIUIUNM