Share
Embed
Mergeable Libraryで 高速なアプリ起動を実現しよう!
https://fortee.jp/iosdc-japan-2024/proposal/b8dc0c4a-b576-4395-974f-a52cfc2bc6a0
iOSDC 2024 Day 1 13:55~ Track A
Transcript
51 slides
-
͢͜ͱ • ϑϨʔϜϫʔΫͷϦϯΫͷΈͷ͓͞Β͍ • ैདྷͷख๏ͱτϨʔυΦϑ • Mergeable Libraryͷհ • Έͱઃఆํ๏
• ઃఆʹΑΔڍಈΛݟͯΈΔ • Mergeable XCFrameworkͷ -
͢͜ͱ • ϑϨʔϜϫʔΫͷϦϯΫͷΈͷ͓͞Β͍ • ैདྷͷख๏ͱτϨʔυΦϑ • Mergeable Libraryͷհ • Έͱઃఆํ๏
• ઃఆʹΑΔڍಈΛݟͯΈΔ • Mergeable XCFrameworkͷ -
͢͜ͱ • ϑϨʔϜϫʔΫͷϦϯΫͷΈͷ͓͞Β͍ • ैདྷͷख๏ͱτϨʔυΦϑ • Mergeable Libraryͷհ • Έͱઃఆํ๏
• ઃఆʹΑΔڍಈΛݟͯΈΔ • Mergeable XCFrameworkͷ -
Dynamic Frameworkͷಛ Ϗϧυ࣌ؒ Ϗϧυ࣌ʹϦϯΫ͕ෆཁͳͨΊΊ Ωϟογϡ ϏϧυࡁΈͷϑϨʔϜϫʔΫΛ࠶ར༻ՄೳͳͨΊΩϟογϡ͍͢͠ Xcode Preview ར༻Մೳ ىಈͷӨڹ
ϥϯλΠϜͰϦϯΫ͢ΔͨΊىಈ࣌ؒʹӨڹ͕͋Δ ΞϓϦͷαΠζ embed͕ඞཁɺ࠷దԽ͕͍ͨ͠Ίେ͖͘ͳΓ͕ͪ -
Static Frameworkͷಛ Ϗϧυ࣌ؒ Ϗϧυ࣌ʹϦϯΫ͕ඞཁͳͨΊ͘ͳΓ͕ͪ Ωϟογϡ ϦϯΫ͢͠ඞཁ͕͋Γޮ͖ͮΒ͍ Xcode Preview ར༻ෆՄ ʢͨͩ͠Xcode
16͔Βαϙʔτʣ ىಈͷӨڹ Өڹ͕ͳ͍ ΞϓϦͷαΠζ embed͕ෆཁɺෆཁͳ࣮ͷ࠷దԽ͕ޮ͖͘͢খ͍͘͢͞͠ -
ࢀߟࢿྉ • Swiftʹ͓͚ΔΠϯϙʔτͱϦϯΫͷΈΛ୳Δ - Speaker Deck • https://speakerdeck.com/kishikawakatsumi/ swiftniokeruinpototorinkufalseshi-zu-miwotan-ru •
Link fast: Improve build and launch times - WWDC22 • https://developer.apple.com/videos/play/wwdc2022/110362 -
Dynamic Framework Static Framework Ϗϧυ࣌ؒ Ί Ϗϧυ࣌ʹϦϯΫ͕ෆཁ Ωϟογϡ͍͢͠ Ί Ϗϧυ࣌ʹϦϯΫ͕ඞཁ
Ωϟογϡͮ͠Β͍ Ωϟογϡ ͍͢͠ ͮ͠Β͍ Xcode Preview Մೳ ෆՄ ʢXcode 16Ҏ߱Մೳʣ ىಈ Өڹ͕͋Δ ʢىಈ࣌ͷϦϯΫ͕ൃੜʣ Өڹ͕ͳ͍ ΞϓϦͷαΠζ େ͖͘ͳΓ͕ͪ embed͕ඞཁ ࠷దԽͮ͠Β͍ খ͞Ί embed͕ෆཁ ࠷దԽ͍͢͠ ϦϦʔε࣌ʹ༗ར ։ൃ࣌ʹѻ͍͍͢ -
ैདྷख๏ͷ • Debug, ReleaseؒͰϏϧυઃఆ͕ҟͳΔͨΊෳࡶʹͳΔ • ͳʹ͔Ϗϧυ࣌ͷ͕ى͖ͨͱ͖ͷௐ͕͍ࠪ͠ʢγϯϘϧॏෳͳͲʣ • ຒΊࠐΈʢembedʣͷ੍ޚ͕͍͠ • Static
Frameworkembedͯ͠ͳΒͳ͍ • Ϧιʔεόϯυϧͷѻ͍ʹؾΛ͚ͭΔඞཁ͕͋Δ • `Bundle(for: )` ͷϥϯλΠϜͷڍಈ͕มΘͬͯ͠·͏ -
Resource Bundle Framework Bundle MyApp.app/Frameworks/ MyUI.framework Dynamic Framework Static Framework
Main Bundle MyApp.app/Frameworks/ MyUI.framework Static Frameworkͷ BundleࢀরͰ͖ͳ͍ let bundle = Bundle(for: MyClass.self) -
Mergeable Library • ϝλσʔλΛ࣋ͬͨ৽͍͠Dynamic Library • Build Con fi gurationʹԠͯ͡ϦϯΫํࣜΛΓସ͑ΒΕΔ
• DebugϏϧυ࣌Dynamic Frameworkͱͯ͠ৼΔ͏ • ReleaseϏϧυ࣌Static Frameworkͱͯ͠ৼΔ͏ ਤͷҾ༻ɿhttps://developer.apple.com/documentation/xcode/con fi guring-your-project-to-use-mergeable-libraries -
DebugϏϧυ࣌ - ΞϓϦόϯυϧ • Ϛʔδ͞ΕͨDynamic Framework͕ReexportedBinariesͱͯ͠࠶ΤΫεϙʔ τ͞ΕɺDynamic Link͞ΕΔ Dynamic Framework͕
Mergeable Framework͔Β ࠶ΤΫεϙʔτ͞Ε embed͞ΕΔ -
Ϛʔδ͞ΕͨόΠφϦΛݟͯΈΑ͏ $ nm -gU GiginyanPay.app/GiginyanPay 0000000100014070 S _$s10NyanPayKit7TopViewV7SwiftUI0E0AAMc 0000000100008f78 T
_$s11NyanPayCore6WalletC6amountACSi_tcfC 0000000100014268 S _$s9NyanPayUI10QRCodeViewV05SwiftC00E0AAMc 00000001000141f0 S _$s9NyanPayUI9ImageViewV05SwiftC00E0AAMc 0000000100014150 S _NyanPayCoreVersionNumber 0000000100014120 S _NyanPayCoreVersionString 0000000100014068 S _NyanPayKitVersionNumber 0000000100014038 S _NyanPayKitVersionString 00000001000141e8 S _NyanPayUIVersionNumber 00000001000141b8 S _NyanPayUIVersionString 0000000100000000 T __mh_execute_header 00000001000054ac T _main • ΞϓϦόΠφϦʹଞͷϑϨʔϜϫʔΫͷγϯϘϧʢ࣮ʣ͕ຒΊࠐ·Ε͍ͯ Δ͜ͱ͕Θ͔ΔʢStatic Link) -
Resource Lookup • Dynamic / Staticͷ߹͍ͣΕ`Bundle(for:)`ʹΑΔϦιʔεόϯυϧͷऔಘ ΛϥϯλΠϜͰಡΈସ͑ͯ͘ΕΔ Framework Bundle MyApp.app/Frameworks/
MyUI.framework Dynamic Framework Static Framework Framework Bundle MyApp.app/Frameworks/ MyUI.framework -
embed͞ΕͨStatic Framework $ nm -gU GiginyanPay.app/Frameworks/NyanPayUI.framework/NyanPayUI GiginyanPay.app/Frameworks/NyanPayUI.framework/NyanPayUI: no symbols •
embed͞ΕͨStatic FrameworkͷόΠφϦʹγϯϘϧؚ͕·Εͳ͍ • ϦιʔεόϯυϧͷΈembedͰ͖Δ ϦιʔεͷΈͷ ϑϨʔϜϫʔΫ -
͢ͳΘͪ • ։ൃ࣌ϑϨʔϜϫʔΫ͕Dynamic Frameworkͱͯ͠ग़ྗ͞ΕɺDynamic Link͞ΕΔͷͰ։ൃऀମݧ্͕ • ϦϦʔε࣌Ϛʔδ͞ΕͨϑϨʔϜϫʔΫ͕Static Link͞ΕΔͷͰɺىಈ࣌ؒ ΞϓϦͷ༰ྔ͕ݮ͞ΕΔ •
Ϧιʔεؚ͕·ΕΔ߹ࣗಈతʹಡΈସ͑ΒΕΔ • ͳΜ͔શ෦ྑ͍ײ͡ʹͳΔ -
ϕϯνϚʔΫ Dynamic Framework Mergeable (Debug/Re-export) Mergeable (Release) Ϗϧυ࣌ؒ ΫϦʔϯϏϧυ 185s
151.6s 84.3s Ϗϧυ࣌ؒ ࠩϏϧυ 7s 79.3s 10.16s ΞϓϦαΠζ 81.9MB 82MB 6.8MB -
࠶ΤΫεϙʔτ • Mergeable Framework͔Βɺ௨ৗͷDynamic FrameworkΛநग़͠ɺ ReexportedBinariesͱͯ͠࠶ΤΫεϙʔτ͢Δ • େ͜ΕͰྑ͍͕ɺίϐʔίετ͕ແࢹͰ͖ͳ͘ͳΔ DebugϏϧυ ௨ৗ
ґଘͷ͕ଟ͍߹ ࠶ΤΫεϙʔτʹ ͕͔͔࣌ؒΓϏϧυ͕ վળ͠ͳ͍ -
%ZOBNJD-JCSBSZͷϚʔδ • MAKE_MERGEABLE=YESΛࢦఆ͢Δͱɺ*.debug.dylibʹDynamic FrameworkͷόΠφϦ͕Ϛʔδ͞ΕΔ • ΘΓʹReexportedBinariesग़ྗ͞Εͳ͘ͳΓɺίϐʔίετ͕ͳ͘ͳΔ DebugϏϧυ MAKE_MERGEABLE =YES ґଘͷ࣮dylibʹ౷߹͞ΕΔ
Merged Dynamic Binary 239KB -> 417KB $ nm -gU GiginyanPay.debug.dylib 0000000000008c88 T _$s10NyanPayKit7TopViewV4bodyQrvg 000000000001d3b0 S _$s10NyanPayKit7TopViewV4bodyQrvpMV 000000000001da4c S _$s10NyanPayKit7TopViewV4bodyQrvpQOMQ 0000000000008938 T _$s10NyanPayKit7TopViewV6wallet0aB4Core6WalletCvM 00000000000085fc T _$s10NyanPayKit7TopViewV6wallet0aB4Core6WalletCvg 0000000000020910 S _$s10NyanPayKit7TopViewV6wallet0aB4Core6WalletCvpMV 0000000000008870 T -
ϕϯνϚʔΫ Dynamic Framework Mergeable (Debug/Merge) Mergeable (Release) Ϗϧυ࣌ؒ ΫϦʔϯϏϧυ 185s
149.3s 84.3s Ϗϧυ࣌ؒ ࠩϏϧυ 7s 7.6s 10.16s ΞϓϦαΠζ 81.9MB 8.4MB 6.8MB -
ߟɿཧ͕ग़͍ͯͳ͍݅ • ΫϦʔϯϏϧυ࣌ͷDynamic Frameworkߏஙʹ͔͔ΔॳظίετΛࠩϏϧυ ͰϖΠͰ͖͍ͯͳ͍ • Ծઆ1: μϛʔϓϩδΣΫτͷͨΊ࣮͕΄΅ͳ͍ • Static
LinkͰ͋ͬͨͱͯ͠ϦϯΫ͕͔࣌ؒͳΓ͍ • Ծઆ2: ࠶Ϗϧυ࣌ͷมߋ͕ͳ͍ • Static FrameworkͰ͋ͬͯΩϟογϡ͕شൃͮ͠Β͘ɺDynamic FrameworkͷΩϟογϡͷརΛੜ͔͍ͤͯͳ͍ -
Ϛʔδ͢Δଆͷઃఆ • Ϛʔδ͢ΔଆʢΞϓϦଆʣ • Create Merged Library: Automatic/Manual • Automatic:
ࢠґଘΛϚʔδՄೳʹ | Manual: ࢦఆͨ͠ͷͷΈ • Ϛʔδ͢ΔͷΛFrameworks, Libraries, and Embedded ContentʹՃ • ໌ࣔతͳґଘ(ґଘ)ͷΈ͕Ϛʔδ͞ΕΔ • Ϧιʔε͕͋ΔͷͷΈEmbed & Sign Create Merged Binary Frameworks, Libraries, and Embedded Content 1 2 1 2 -
Ϛʔδ͞ΕΔଆͷઃఆ • Ϛʔδ͞ΕΔଆʢϑϨʔϜϫʔΫଆʣ • Build Mergeable Library • ϑϨʔϜϫʔΫΛϚʔδՄೳʹ͢Δ͔ •
ManualͳΒBuild Mergeable LibraryΛYES • MAKE_MERGEABLE • ϑϨʔϜϫʔΫΛϚʔδ͢Δ߹YES • ࢦఆ͠ͳ͍ͱσόοά࣌࠶ΤΫεϙʔτ͢Δ Build Mergeable Library MAKE_MERGEABLE 2 2 1 1 -
XCFrameworkͷMergeableԽ • ϏϧυࡁΈόΠφϦ(XCFramework)Mergeable Libraryͱͯ͠Ͱ͖Δ • αΠζେ͖͘ͳΔ͕ɺϥΠϒϥϦͷར༻ऀ͕Dynamic/Static྆ํΛ ͍Θ͚Δ͜ͱ͕Ͱ͖Δ • Framework͕Mergeable Library͔Ͳ͏͔ɺmetadataͷ༗ແͰผͰ͖Δ
• LC_ATOM_INFOΛϩʔυ͢Δ͔Ͳ͏͔ $ otool -l MyFramework.xcframework/ios-arm64/MyFramework.framework/MyFramework Load command 49 cmd LC_ATOM_INFO cmdsize 16 dataoff 133328 datasize 63984 -
Swift PackageͷMergeable XCFrameworkԽ • giginet/Scipio͢ͰʹMergeable LibraryαϙʔτࡁΈ • ଟ͘ͷSwift Package͜Ε͚ͩͰMergeable XCFrameworkԽͰ͖Δ
• https://giginet.github.io/Scipio/documentation/scipio/mergeable-library Swift PackageΛͬͨ ڊେͳґଘάϥϑͷΩϟογϡઓུ iOSDC2023 $ scipio create path/to/MyPackage --framework-type mergeable --enable-library- evolution -
·ͱΊ • Mergeable LibraryͷΈͱಋೖํ๏ • ࠓ͙͢Create Merged Binary > Automatic
• MAKE_MERGEABLE=YESΛΕͣʹ • Prebuilt Frameworkࠓ͙͢Mergeable FrameworkͰʂ • Ϧιʔεؚ͕·ΕΔ߹ͷରॲํ๏ -
ࢀߟࢿྉ - Mergeable Library - • Meet mergeable libraries -
WWDC23 - Videos - Apple Developer • https://developer.apple.com/videos/play/wwdc2023/10268/ • Con fi guring your project to use mergeable libraries | Apple Developer Documentation • https://developer.apple.com/documentation/xcode/con fi guring-your- project-to-use-mergeable-libraries • https://github.com/kateinoigakukun/MergeableLibraryInternals • Understanding mergeable libraries • https://www.polpiella.dev/understanding-mergeable-libraries -
ࢀߟࢿྉ - Metrics- • Reducing your app’s launch time |
Apple Developer Documentation • https://developer.apple.com/documentation/xcode/reducing-your-app-s- launch-time • Ultimate application performance survival guide - WWDC21 - Videos - Apple Developer • https://developer.apple.com/videos/play/wwdc2021/10181/ • What’s new in Xcode 16 - WWDC24 - Videos - Apple Developer • https://developer.apple.com/videos/play/wwdc2024/10135/ -
Mergeable Libraryઃఆ xccon fi g Xcode GUI આ໌ MERGED_BINARY_TYPE NO/automatic/manual
Create Merged Binary ϦϯΫઌͷλʔήοτΛϚʔδ͢Δ͔ AutomaticͩͱࣗಈతʹϚʔδՄೳʹ͢Δ Manualͩͱ໌ࣔతʹࢦఆͯ͠ΔͷͷΈ MERGEABLE_LIBRARY YES/NO Build Mergeable Library ϥΠϒϥϦΛϚʔδՄೳʹ͢Δ͔ɻManual ͷࡍ໌ࣔతʹࢦఆ͕ඞཁ MAKE_MERGEABLE YES/NO ઃఆෆՄ σόοάϏϧυ࣌ʹϥΠϒϥϦΛϦϯΫ࣌ʹ Ϛʔδ͢Δ͔ɺ࠶ΤΫεϙʔτ͢Δ͔ -
ىಈ࣌ؒܭଌͷ4ͭͷํ๏ Instruments Performance Tests MetricKit Xcode Organizer ར༻͢Δͷ App Launch
Template XCTApplicationLaunch Metric MXAppRunTimeMetric Xcode Organizer ར༻ͷ؆୯͞ ˕ ◦ ˚ ˕ ࣮ߦ λΠϛϯά ։ൃதͷҙ UI Tests࣮ߦ࣌(CIͳͲ) ΞϓϦ࣮ߦ࣌ɺϦϦʔεޙ ϦϦʔεޙ ࣮ ෆཁ UIςετέʔεΛ࣮ ϝτϦΫεऔಘ࣌ͷίʔϧ όοΫΛ࣮ ෆཁ ༻్ ։ൃ࣌ͷσόοά σάϨʔγϣϯͷݕ ΤϯυϢʔβʔͷϩάΛ ࡉ͔͘औΔ ʢϩάج൫ͷૹ৴ͳͲʣ ΤϯυϢʔβʔͷ Λόʔδϣϯຖʹ Δ