Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
安定的 60 fps をめざす / the way to 60 fps
Search
Taishi Ikai
January 29, 2018
Technology
19
5.6k
安定的 60 fps をめざす / the way to 60 fps
iOS app
at Otemachi.swift x Kyobashi.swift #02
https://kyobashi-swift.connpass.com/event/75379/
Taishi Ikai
January 29, 2018
Tweet
Share
More Decks by Taishi Ikai
See All by Taishi Ikai
日経電子版でApp内課金を導入した話 / Nikkei uses In-App Purchase
ikait
2
2.8k
紙面ビューアーを支える サーバーレスアーキテクチャ / serverless architecture supports Nikkei's paper viewer
ikait
43
40k
SwiftとCoreTextと文字組み
ikait
1
650
Typography and Fonts と日本語フォントまわり
ikait
2
3.1k
Other Decks in Technology
See All in Technology
Delegate authentication and a lot more to Keycloak with OpenID Connect
ahus1
0
240
[OCI Technical Deep Dive] OracleのAI戦略(2025年8月5日開催)
oracle4engineer
PRO
1
250
MCP認可の現在地と自律型エージェント対応に向けた課題 / MCP Authorization Today and Challenges to Support Autonomous Agents
yokawasa
5
2.5k
データモデリング通り #2オンライン勉強会 ~方法論の話をしよう~
datayokocho
0
190
GISエンジニアよ 現場に行け!
sudataka
1
140
Telemetry APIから学ぶGoogle Cloud ObservabilityとOpenTelemetryの現在 / getting-started-telemetry-api-with-google-cloud
k6s4i53rx
0
160
「Roblox」の開発環境とその効率化 ~DAU9700万人超の巨大プラットフォームの開発 事始め~
keitatanji
0
140
オブザーバビリティ文化を組織に浸透させるには / install observability culture
mackerelio
0
300
Exadata Database Service on Dedicated Infrastructure セキュリティ、ネットワーク、および管理について
oracle4engineer
PRO
1
330
はじめての転職講座/The Guide of First Career Change
kwappa
5
4.4k
EKS Pod Identity における推移的な session tags
z63d
1
110
Amazon Bedrock AgentCoreのフロントエンドを探す旅 (Next.js編)
kmiya84377
1
160
Featured
See All Featured
We Have a Design System, Now What?
morganepeng
53
7.7k
Gamification - CAS2011
davidbonilla
81
5.4k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
6k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
How STYLIGHT went responsive
nonsquared
100
5.7k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
890
A designer walks into a library…
pauljervisheath
207
24k
Why Our Code Smells
bkeepers
PRO
338
57k
Designing Experiences People Love
moore
142
24k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.5k
Transcript
1 ҆ఆత 60 fps ΛΊ͟͢ ழࣂ େࢤ ຊܦࡁ৽ฉࣾ Otemachi.swift x
Kyobashi.swift #02
<ಈը>
3 FPS Frames Per Second ͷུ 1 ඵؒʹදࣔ͢ΔϑϨʔϜ ͜Ε͕େ͖͍ͱɺΒ͔ʹݟ͑ΔʢňψϧψϧʼnײɺUX
ʹӨڹ͢ΔԾઆʣ UIScreen.main.maximumFramesPerSecond ࠷େ FPS Λऔಘ͢ΔɻiOS σόΠεͰɺ௨ৗ 60 ϝΠϯεϨουͰߦ͏ॲཧͷͱॏ͞ΛۃྗݮΒͯ͠ɺ࣮ݱΛࢦ͢ ࠓ͔ΒɺҰൠతͳઓུͱɺView ଆʹϑΥʔΧεͨ͠Λ͠·͢ FPS ʹ͍ͭͯ
4 ඞཁͳ͜ͱ͚ͩ͢Δ UIεϨουΛܰ͘͢ΔɺϒϩοΫ͠ͳ͍ Կ͠ͳ͍ ͘͢Δ ༧ΊΔ → Instruments Λݟͳ͕Βɺॏ͍ͱ͜Ζ͔ΒରԠΛ͍ͯ͘͠ FPS
ࢹʹΑΔ֬ೝɺInstruments ͷ Core Animation Ͱ֬ೝ ՄೳͳݶΓݹ͍Λར༻ ํ
5 ͦͷ࣌ͰෆཁͳσʔλΛ֎͢ ͍ͬͯͳ͍ϩδοΫΛফ͢ ֤ͰΔඞཁ͕͋Δͷ͚ͩड͚औΔ ͲͷͰಉ͡ॲཧʹͳΔͳΒɺ API Ͱܗ͓ͯ͘͠ unixtime Ͱड͚औΔͳͲ Ͳ͏ͯ͠
UI εϨου͡Όͳ͍ͱͰ͖ͳ͍͜ͱ͚ͩΔ ❌ ௨৴σΟεΫॻ͖ࠐΈ ❌ NSAttributedString ͷੜɺηϧͷߴ͞ͷܭࢉɺΦϑεΫϦʔϯඳը ඞཁͳ͜ͱ͚ͩΔ
6 UITableViewCell, UITableView(Header|Footer)View ͳͲ࠶ར༻͢Δ εΫϩʔϧͷͨͼʹੜ͢Δͱ݁ߏॏ͍ ϖʔδ UI ͳΒɺVC ࠶ར༻Ͱ͖Δͱྑͦ͞͏ ಉ͡ΧϥʔɺϑΥϯτɺਖ਼نදݱɺϑΥʔϚολʔ࠶ར༻͢Δ
UIColor, UIFont, NSRegularExpression, DateFormatter, NumberFormatter ຖੜ͢Δඞཁͳ͚ΕఆԽ͢ΔɺΩϟογϡ͢Δ Computed property ຖճධՁ͞ΕΔ νϦπϞͰ݁ߏͳϘτϧωοΫʹͳ͍ͬͯΔ͜ͱ Կ͠ͳ͍
7 ߴͳ DBɺΩϟογϡɺπʔϧΛ͏ Realm ͳͲ ंྠͷ࠶ൃ໌͍ͯ͠ͳ͍͔ UITableViewCell ͷߴ͞ܭࢉɺcell ͷͳͲɺԆͤ͞ʹ͍͘ ؤுͬͯ͘Δɺࣄલʹϩʔυ͢Δ
͘Δ
8 UITableView ͷଓ͖ΛಡΉͱ͖ͳͲɺUITableView ʹηϧΛՃ͢Δલʹɺ ઌʹߴ͞Λܭࢉ͓ͯ͘͠ & ΦϑεΫϦʔϯඳըͪ͠Ό͏ ϝϞϦޮͷͰɺඍົ͔͠Εͳ͍? ༧ΊΔ
۩ମతʹ 9
UITableViewCell Λܧঝ͢ΔΫϥεͰ init() ͳͲͰ UILabel, UIImageView Λ contentView ʹՃ Constraints,
StackView Λ͔ͭͬͯஔ cellForRow(at indexPath:) ͷதͰ dequeueReusableCell(withIdentifier identifier:, for indexPath:) Ͱ ηϧΛऔಘ (όοΫάϥϯυͰ) ը૾Λऔಘͯ͠ UIImageView ʹ͢ ηϧͷཁૉ͕૿͑Δʹ࿈Εͯɺॏ͘ͳͬͯ͘Δ 10 UITableView Ͱͷσʔλදࣔ
UITableViewCell Λܧঝ͢ΔΫϥεͰ init() ͳͲͰ UILabel, UIImageView Λ contentView ʹՃ Constraints,
StackView Λ͔ͭͬͯஔ cellForRow(at indexPath:) ͷதͰ dequeueReusableCell(withIdentifier identifier:, for indexPath:) Ͱ ηϧΛऔಘ (όοΫάϥϯυͰ) ը૾Λऔಘͯ͠ UIImageView ʹ͢ ηϧͷཁૉ͕૿͑Δʹ࿈Εͯɺॏ͘ͳͬͯ͘Δ 11 UITableView Ͱͷσʔλදࣔ
12 ҆ఆత 60 fps Λ࣮ݱ͢ΔʹɺAuto Layoutɺ Stack View Ͱ͍͠ ൺֱత৽͍͠Ͱɺཁૉ
(view) ͕ଟ͘ͳΔͱΧΫ͍ͭͯ͘Δ ಛʹຊޠ͕ೖΔͱɺϑΥϯτબ Auto LayoutɺखಈϨΠΞτͷਏΈ ηϧͷߴ͞ܭࢉΛࣗͰߦ͏ Ϩϕϧ 1 → 3 ʹ͚͓ͯ͠͠·͢ Auto Layout ΛΊΔ
13 UILabel, UIImageView ͷ frame ΛࣗͰܭࢉͯ͠ஔ͍ͯ͘͠ ߹ʹΑͬͯ Auto Resizing Mask
Λར༻ Auto Layout Ҏલͷ࣌Ͱओྲྀ ίʔυߦׂΓͱ૿Ճ ߴ͞ܭࢉखಈ UILabel, UIImageView ϝΠϯεϨουͰ৮ΕΔඞཁ͕͋ΔͷͰɺ NSString, NSAttributedString ͷ boundingRect Λར༻ Ϩϕϧ1: खಈϨΠΞτ + Auto Resizing Mask
14 UILabel, UIImageView ΛΘͣʹɺखಈͰඳը͢Δ શͯखಈͰϨΠΞτ UIView (, UITableViewCell) ͷ draw(_:)
Λ্ॻ͖ͯ͠ɺ NSString, NSAttributedString ͷ draw ܥͰॻ͖ࠐΉ NSAttributedString ɺόοΫάϥϯυͰ০͓ͯ͘͠ Ϩϕϧ2: ඳ͘
15 override func draw(_ rect: CGRect) { guard let context
= UIGraphicsGetCurrentContext() else { return nil } var remainRect = rect var attributedStringRect = self.attributedString.boundingRectCached( scope: "emblem", size: remainRect.size, options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine]) self.attributedString.draw( with: remainRect, options: [.usesLineFragmentOrigin, .truncatesLastVisibleLine], context: nil ) remainRect.origin.y += attributedStringRect.bounds.height remainRect.size.height -= attributedStringRect.bounds.height // // ཁૉͷ܁Γฦ͢ // UIGraphicsEndImageContext() }
16 UILabel, UIImageView ΛΘͣʹɺखಈͰඳը͢Δ drawRect ͤͣʹɺόοΫάϥϯυͰ UIGraphicsBeginImageContextWithOptions ͯ͠ɺίϯςΩετΛ࡞Γɺͦ͜ʹॻ͖ࠐΉ ࠷ऴతʹɺඳըྖҬͷ CGImage
Λ࡞͓͍ͬͯͯɺ ͦΕΛΩϟογϡ͓ͯ͘͠ ॾʑͷॲཧΛ࣮֬ʹόοΫάϥϯυʹ ࿈Ε͍͚ͯΔͱ͍͏ϝϦοτ Ϩϕϧ3: CGImage ΛόοΫάϥϯυͰͭͬͯ͘షΔ
17 Func getImage(with bounds: CGSize) -> CGImage { if let
image = CacheStore.get(/* ݅ */) { return image } // όοΫάϥϯυΩϡʔͰɺcontext Λ࡞ UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0) guard let context = UIGraphicsGetCurrentContext() else { return nil } // ࣗͰߴ͞ܭࢉΛ͠ͳ͕ΒɺNSAttributedString ͷ draw ͳͲͰ context ʹॻ͖ࠐΜͰ͍͘ attributedString.draw(with: bounds, options: drawingOptions, context: nil) // ऴΘͬͨΒ makeImage() ͯ͠ context Λऴ͑Δ let image = context.makeImage() UIGraphicsEndImageContext() if let image = image { CacheStore.set(image, forKey: key) } return image } ը૾όοΫάϥϯυͰऔಘͯ͠ɺ CGLayer ͷ cgImage ʹషΔ
18 UIView Ͱ backgroundColor Λ୯৭ʹ UIView Ͱ opaque: true ޮՌ͋·Γ࣮ײͰ͖ͣ...
> Blended view layers often cause slow table scrolling. https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/MeasuringGraphicsPerformance.html Blended Layers Λͳ͘͢
ϝΠϯεϨουΛۃྗΘͳ͍ҙ͕ࣝॏཁ όοΫάϥϯυͰ CGImage ʹॻ͖ࠐΉͷޮՌ͋ͬͨ ඳըʹؔΘΔॲཧΛશͯόοΫάϥϯυʹ͍͚ͬͯͨ ͘ͳΓ͗͢Δͱന͍ηϧ͕ը໘ʹͰͯ͘Δ Auto Layout, StackView Ίͯɺ͍ͩͿૣ͘ͳͬͨ
খ͍͞Օॴ͕ੵͬͯҾ͔͔ͬΔ͜ͱ͕ଟʑ͋ͬͨ NSAttributedString UIFont ͰΩϟογϡ͔ఆԽ 19 ·ͱΊ 20% 10% 40% 30% खಈϨΠΞτ CGImage νϦ
Pinterest ͷਓ͕ͨͪத৺ʹ։ൃ͍ͯ͠Δඇಉظతͷ UI ඳըϑϨʔϜϫʔΫ RxSwift ͱΈ߹Θͤͯ͏ࣄྫ͕গͳ͔ͬͨ & View ·ΘΓ૯ͱ͔͕ͬ͑ඞཁͦ͏ͩͬͨͷͰݟૹͬͨ "Native"
Ͱ͋Δҙٛͱͯ͠ 60 fps ͷୡΛҙ͍ࣝͯ͠Δ Core Text ͳͲϨΠϠʔͳ API ʹׂΓͱ৮͍ͬͯͨ & ݟ͕গͳ͘ϦϦʔεʹؒʹ߹ΘͤΔࣗ৴͕࣋ͯͣɺݟૹͬͨ 20 ࠓޙݕ౼͍ͨ͠ چ໊শ: AsyncDisplayKit
21 ழࣂ େࢤʢ͍͔͍ ͍ͨ͠ʣ ຊܦࡁ৽ฉࣾॴଐͷΤϯδχΞ ͍ͭͬͯ͘Δͷ: iPhone ͷܦిࢠ൛ΞϓϦ iPhone /
iPad ͷࢴ໘ϏϡʔΞʔΞϓϦ ΞϓϦͷόοΫΤϯυܥ (w/αʔόʔϨε) About me