Upgrade to Pro — share decks privately, control downloads, hide ads and more …

為什麼 App 卡卡的

Johnlin
November 08, 2020

為什麼 App 卡卡的

iPlayground 2020 Keynote

Johnlin

November 08, 2020
Tweet

More Decks by Johnlin

Other Decks in Programming

Transcript

  1. Safe Area @johnlinvc John Lin (@johnlinvc) • ኺ iPhone OS

    2 ։࢝ሜ Obj-Cɻ • ໨લࡏ West Pharmaceutical ᙛ DevOpsɻ
 ሢ໳ሜڅ։ᚙऀʢแؚࣗݾʣ༻త޻۩ɻ
 ؐ༗मผਓత Bugɻ
  2. Safe Area @johnlinvc Swift Taipei • ኺ 2016 ೥ 1/14։࢝ɼࡏ㑌ݸ݄తୈҰݸᜌ፨ೋᎯ㭎ɻ౸໨લቮៃ㭎ྃ

    ઀ۙ 60 ࣍ᡉ။ɻ • ఏڙେՈҰݸೳⴺ์ᱷ౼࿦ Swift త஍ํɻ • ڧྗ㐸ٻߨऀதɻ୞ཁ࿨ Swift ᜗ඍ༗૬᮫త౎ඇৗᓣܴɻ
  3. Safe Area @johnlinvc iPlayground • ڈྃ iOSDC Japan ޙ᧷ಘ୆ᖯ໵ጯ֘༗ •

    ᙛ৔ങྃ iosdc.tw ໢Ҭɻ • ޙိܾఆཁڣ iPlaygroundɻ
 iosdc.tw ။ಋ౸ iplayground.io
  4. Safe Area @johnlinvc iPlayground తओ୊ • ᙛવؐੋᅴ៴ࡏ App (ෆੋ˖ʽҰʽҰ) ্,ɻ

    • ෼ڗ૬᮫తመ຿ʢҏཕʣៃᱛɻ • ୳ࡧߋଟ։ᚙ্తՄೳੑɻ
  5. Safe Area @johnlinvc ਓ؟తහ㕔౓ • 1991 ೥తݚڀɻࢹਆៃࡉ๔ሣᦊນરᗜత൓ጯɻ • ༻ిۃఁଌਓᱪࢹਆៃሣ CRT

    ᦊນરᗜత൓ጯɻ • Human electroretinogram responses to video displays,
 fluorescent lighting, and other high frequency sources
  6. Safe Area @johnlinvc ճᰶཁଟշ࠽ⴺշ • 2015 ೥తݚڀɼ
 ଌࢼ࢖༻ऀሣᨀ߇༌ೖతࢹ᧷ճᰶԆᬌ
 త༰೜౓ɻ •

    How Much Faster is Fast Enough? 
 User Perception of Latency &
 Latency Improvements in
 Direct and Indirect Touch
  7. Safe Area @johnlinvc > զ၇ိ໰Ұݸ኷؆ᄸత໰୊ɿզ၇ॴሜաతఔࣜɼେଟ౎ੋኺ಄౸ඌɺ ҰߦҰߦԟԼࣥߦɼࣥߦ׬ඟɼఔࣜब݁ଋʀಹኄɼҰݸ GUI ጯ༻ఔࣜ —ແ࿦ੋզ၇ݱࡏਖ਼ࡏላशత iOS

    ᢛ Mac OS Xɺؐੋଖଞฏ୆—ҝॄኄ ෆੋଧ։೭ޙҰ࿏ࣥߦ౸ఈ݁ଋɼࣕੋ။ఀཹࡏᦊນத౳଴զ၇ૢ࡞ʁ KKBOX iOS/Mac OS X جૅ։ᚙڭࡐ
  8. Safe Area @johnlinvc Run Loop ᔒ༗ݻఆతिظ • ཁ౳౸ݱ༗త loop 䋯׬೭ޙɼ࠽။䋯ԼҰݸ

    loopɻ • ೗Ռࡏ Event Handler ཫ໘၏ྃଠଟࣄɼब။ᩋԼҰݸ loop Ԇޙ։ ࢝ɻ
 
 0 35 70 105 140 Loop 1 Loop 2 Loop 2
  9. Safe Area @johnlinvc Ұݸ loop Ֆྃଠଟ࣌ؒ • ႔ཧ׈ಈ௒ա 11 ms

    => ׈ಈ㠡㠡త • ႔ཧᴍ㐝௒ա 69 ms => ᴍ㐝㠡㠡త
  10. Safe Area @johnlinvc ॏෳ࢖༻ View/Cell • UICollectionView
 dequeueReusableCell(withReuseIdentifier:for:) • UIImage


    Cached: init(named:)
 Not Cached: init(contentsOfFile:) • MKMapView
 dequeueReusableAnnotationView(withIdentifier:)
  11. Safe Area @johnlinvc Reusable • https://github.com/AliSoftware/Reusable • ՄҎ༻ Type Safe

    తํ๏ိఆٛ Reuse identifier. final class CustomCell: UITableViewCell, Reusable tableView.register(cellType: theCellClass.self) let cell = tableView.dequeueReusableCell(for: indexPath) as MyCustomCell
  12. Safe Area @johnlinvc ଟ֩৺႔ཧث • iPhone 12 ্༗ 6 ݸ

    CPU ֩৺ɻ • ՄҎಉ࣌ࣥߦଟݸࣥߦॹɻ • ୞ཁ೺ࣄ৘෼ࢄ౸֤ݸ֩৺ɼबՄҎॖ୹ run loop ႔ཧ࣌ؒɻ
  13. Safe Area @johnlinvc Dispatch • ࢖༻ Obj-C block & Swift

    closure ိ෧᧋ Thread APIɻ • جຊ্बੋ೺ code 㟚౸ queue ཫɼሏब။㢨㟬ࣥߦɻ
  14. Safe Area @johnlinvc Dispatch • ༻ DispatchQueue.async बՄҎᩋ code ࡏผత

    Thread 䋯ɻ DispatchQueue.global(qos: .background).async { // code to run }
  15. Safe Area @johnlinvc Combine • ՄҎ༻ receive(on:) ੾׵ Thread/Queue Just(1)

    .map { _ in print(Thread.isMainThread) } // true .receive(on: DispatchQueue.global()) .map { print(Thread.isMainThread) } // false .sink { print(Thread.isMainThread) } // false
  16. Safe Area @johnlinvc UIKit ୞ೳࡏ main Thread ݺڣ • UIKit

    ᔒ༗ Thread Safetyɻ • ࡏผత஍ํݺڣత࿩။༗ Error ɻ • UI API called on a background thread: -[UIView initWithFrame:]
  17. Safe Area @johnlinvc ආ໔ UIKit thread ໰୊ • ࡏ Dispatch

    ཫ༻ DispatchQueue.main ੾׵ճ Main Thread • ࡏ Combine ཫ༻ receive(on:) ੾׵ճ Main Thread • ࢖༻ SwiftUI
  18. Safe Area @johnlinvc ආ໔ UIKit thread ໰୊ • ࡏ Dispatch

    ཫ༻ DispatchQueue.main ੾׵ճ Main Thread • ࡏ Combine ཫ༻ receive(on:) ੾׵ճ Main Thread • ࢖༻ SwiftUI
  19. Safe Area @johnlinvc ࢖༻ Swift UI struct ContentView: View {

    @State var clickCount : Int = 0 var body: some View { Button(action: add) { Text("\(clickCount)") .font(.system(size: 120)) } } func add() { clickCount += 1 } }
  20. Safe Area @johnlinvc ࢖༻ Swift UI struct ContentView: View {

    @State var clickCount : Int = 0 var body: some View { Button(action: add) { Text("\(clickCount)") .font(.system(size: 120)) } } func add() { clickCount += 1 } }
  21. Safe Area @johnlinvc ࢖༻ Swift UI struct ContentView: View {

    @State var clickCount : Int = 0 var body: some View { Button(action: add) { Text("\(clickCount)") .font(.system(size: 120)) } } func add() { DispatchQueue.global().async{ clickCount += 1 } } }
  22. Safe Area @johnlinvc ࢖༻ Swift UI struct ContentView: View {

    @State var clickCount : Int = 0 var body: some View { Button(action: add) { Text("\(clickCount)") .font(.system(size: 120)) } } func add() { DispatchQueue.global().async{ clickCount += 1 } } }
  23. Safe Area @johnlinvc ࢖༻ Swift UI • ߋ৽UI ௨ৗ౎ੋಁա @State

    property wrapperɻ • @State ੋ Thread safe తɻՄҎኺ೚Կ Thread मվଞతᆴɻ
  24. Safe Area @johnlinvc ҝॄኄ Home 伴័ੋ༗༻ʁ • ཧ࿦্ɼᙛఔࣜ㠡ࡏ run loop

    தత࣌ީɼੋᔒ㭎๏઀Ꮕᨀ߇ࣄ݅తɻ • طવᔒ㭎๏઀Ꮕࣄ݅ɼ޲্׈తख੎ጯ֘ᔒ༗೚Կ࡞༻࠽ሣʁ
  25. Safe Area @johnlinvc Context Switch • ೺໨લఔࣜతهԱᱪ࿨࢑ଘثత㚎༰
 ه㑚ىိɻ • ೺ԼҰݸఔࣜతهԱᱪ࿨࢑ଘثత㚎༰


    ኺه㑚ཫճ෴ɻ • ೺ PC (Program Counterʣࢦ޲ԼҰݸఔࣜɼ
 ໵बੋ೺߇੍ᒟަڅԼҰݸఔࣜɻ Thread
  26. Safe Area @johnlinvc ߹࡞ࣜ੾׵ • ᙛఔࣜࣥߦ system call ࣌ (

    IO, ݐཱ Threadʣ။೺߇੍ᒟަؐڅ࡞ۀ ܥ౷ɼṜݸ࣌ީब༗ػ။၏੾׵ɻ • ᙛఔࣜࣥߦඇ๏ࢦྩ࣌ (1/0, ᩇෆ߹๏తهԱᱪҐஔʣ။ᨀᚙ trapɼṜ ࣌ީܥ౷໵။औಘ߇੍ᒟɼ໵༗ػ။၏੾׵ɻ
  27. Safe Area @johnlinvc ߹࡞ࣜ੾׵త໰୊ • ೗ՌఔࣜӬԕෆݺڣsystem call ɻ૾ੋԼ໘Ṝᒬɼब။Ӭԕᔒ㭎๏੾ ׵ɻ •

    for true { 1+1} • MacOS 9 Ҏલੋ࢖༻߹࡞ࣜ੾׵ɼॴҎᄸҰఔࣜ༗Մೳ㠡ॅ੔ݸܥ౷
  28. Safe Area @johnlinvc Run loop ੋҰछ߹࡞ࣜ੾׵ • 㑌Ұ࣍త loop ౎ཁ౳

    Event Handler ႔ཧ׬࠽။ਐԼҰݸ loopɻ • Dispatch ཁ౳ݱࡏత task ႔ཧ׬࠽။ަग़߇੍ᒟɻ • ॴҎ༗೚ԿҰݸ Event/Task ႔ཧଠٱɼ App ब။㠡ॅɻ
  29. Safe Area @johnlinvc 0x8BADF00D • ೗Ռ༗ఔࣜաྃ኷ٱ౎ᔒ༗ਐలɻ • Darwin ။⬏ಈ WatchDog

    Timerɻ೺ಹݸఔࣜऴࢭɻ • ࡨޡ୅ᛰबੋ 0x8BADF00D, ate bad foodɻ
  30. Safe Area @johnlinvc ᩋ Run loop ༻ඇ߹࡞੾׵? • ઃఆ㑌ݸ loop

    ՄҎ༻ိ႔ཧ Event త࣌ؒɻᙛ࣌ؒ౸త࣌ީबڧ੍ަ ग़߇੍ᒟɻ • ԼҰݸ loop ࠶៺᠃߶߶ᔒ၏׬తࣄɻ
  31. Safe Area @johnlinvc Bringing Theory Into Practice: A Userspace Library

    for Multicore Real-Time Scheduling • ࡏ Linux త Userspace ্ࣥߦత noncooperative schedulerɻ • ՄҎࡏ࢖༻ऀతఔࣜ㚎໛ٖ OS త੾׵ɻ • ໵बੋ㘸ɼՄҎᩋ UI ෆ။㠡ॅɻ
  32. Safe Area @johnlinvc Մೳతመ࡞ํ๏ • ಛ੡త Combine Scheduler ɼᙛ࣌ؒ౸बఀࢭɼԼҰݸ loop

    ࣗಈॏ ࢼɻ • Swift main branch መᱛதత Async/Await + Actorɼᙛᔒ༗ڞڗهԱᱪ ࣌ɼtask बՄҎॏࢼ׌ᔒ༗ෆ૝ཁత෭࡞༻ɻ
  33. Safe Area @johnlinvc UIKit SwiftUI ඇ߹࡞ࣜ 
 run loop ༏ᴍ

    ࠷੒ख़ ՄҎ೺ॴ༗తࣄ౎ Ҡ౸ଖଞ Thread ሜग़ိతAppҰఆෆ ။㠡㠡 ᠍ᴍ ࠷೉ሜग़ෆ။㠡㠡 తApp ؐෆ੒ख़ ᙘ໘Մೳߋ৽ෆ׬શ ޷૾ؐᔒ༗ਓ၏
  34. Safe Area @johnlinvc ॄኄੋ App 㠡㠡 ? • ᙘ໘తߋ৽ස཰௿ԙ 76Hz

    • ׈ಈ௒ա 11 ms ᔒ༗ճᰶ • ᴍ㐝௒ա 69 ms ᔒ༗ճᰶ
  35. Safe Area @johnlinvc App 㠡㠡త • Run loop తҰݸ loop

    䋯ྃଠٱɻ䇪౸ྃԼҰݸ loopɻ • ᔒ㭎๏ߋ৽ᙘ໘ɻ • ᔒ㭎๏઀Ꮕ༌ೖɻ
  36. Safe Area @johnlinvc ະိల๬ • Async / Await ՄҎᩋզ၇ߋ༰қ೺ࣄ৘Ҡ౸ଖଞ Thread

    ႔ཧɻ • 㘸ෆఆՄҎࡏ App 㚎၏ඇ߹࡞ࣜ schedulingɼ༗ڵझతՄҎ౳౳ိҰ ىݚڀݚڀɻ
  37. Safe Area @johnlinvc References • https://stackoverflow.com/questions/18738453/how-does-the-compiler- know-a-button-has-been-pressed/18739381 • https://www.objc.io/issues/3-views/moving-pixels-onto-the-screen/ •

    https://zonble.gitbooks.io/kkbox-ios-dev/content/responder/run_loop.html • http://pages.cs.wisc.edu/~remzi/OSTEP/ • https://yuriktech.com/2020/03/07/User-Space-Scheduling/ • Apple Developer Documentation
  38. Safe Area @johnlinvc Q&A • ౤ӨยతҐஔࡏ https://bit.ly/3n4rZO4 • John Lin


    Twitter: @johnlinvc • ᓣܴိ Swift Taipei ෼ڗ҃ᡅᡅ