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
640
Typography and Fonts と日本語フォントまわり
ikait
2
3.1k
Other Decks in Technology
See All in Technology
SAE J1939シミュレーション環境構築
daikiokazaki
1
190
完璧を目指さない小さく始める信頼性向上
kakehashi
PRO
0
120
Datasets for Critical Operations by Dataform
kimujun
0
120
生成AIによる情報システムへのインパクト
taka_aki
1
210
みんなのSRE 〜チーム全員でのSRE活動にするための4つの取り組み〜
kakehashi
PRO
2
100
AI工学特論: MLOps・継続的評価
asei
10
2.1k
大規模イベントを支える ABEMA の アーキテクチャ 変遷 2025
nagapad
5
550
サイバー攻撃のシミュレーション:攻撃者の視点からみる防御のむずかしさ!AWSで試してみよう / 20250423 Kumiko Hemmi
shift_evolve
PRO
1
170
Wasmで社内ツールを作って配布しよう
askua
0
160
Expertise as a Service via MCP
yodakeisuke
1
160
LLM開発を支えるエヌビディアの生成AIエコシステム
acceleratedmu3n
0
340
Snowflake のアーキテクチャは本当に筋がよかったのか / Data Engineering Study #30
indigo13love
0
300
Featured
See All Featured
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
8
390
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
50
5.5k
The Power of CSS Pseudo Elements
geoffreycrofte
77
5.9k
KATA
mclloyd
30
14k
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.5k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Code Reviewing Like a Champion
maltzj
524
40k
Side Projects
sachag
455
43k
Building Applications with DynamoDB
mza
95
6.5k
A Tale of Four Properties
chriscoyier
160
23k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.9k
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