การวิเคราะห์และการเพิ่มประสิทธิภาพการเริ่มต้นแอป

ในระหว่างการเริ่มต้นแอป แอปของคุณจะสร้างความประทับใจแรกแก่ผู้ใช้ การเริ่มต้นแอป ต้องโหลดและแสดงข้อมูลที่ผู้ใช้ต้องใช้แอปอย่างรวดเร็ว หาก แอปใช้เวลานานเกินไปในการเริ่มต้น ผู้ใช้อาจออกจากแอปเนื่องจาก รอนานเกินไป

เราขอแนะนําให้ใช้ไลบรารี Macrobenchmark เพื่อวัด การเริ่มต้น ไลบรารีจะให้ภาพรวมและรายละเอียดการติดตามระบบเพื่อดูว่าเกิดอะไรขึ้นบ้าง ในระหว่างการเริ่มต้น

การติดตามระบบให้ข้อมูลที่เป็นประโยชน์เกี่ยวกับสิ่งที่เกิดขึ้นในอุปกรณ์ ซึ่งช่วยให้คุณเข้าใจสิ่งที่แอปทำในระหว่างการเริ่มต้นและระบุ พื้นที่ที่อาจต้องเพิ่มประสิทธิภาพ

หากต้องการวิเคราะห์การเริ่มต้นแอป ให้ทำดังนี้

ขั้นตอนในการวิเคราะห์และเพิ่มประสิทธิภาพการเริ่มต้นระบบ

แอปมักจะต้องโหลดทรัพยากรที่เฉพาะเจาะจงในช่วงเริ่มต้น ซึ่งเป็นสิ่งสำคัญสำหรับ ผู้ใช้ปลายทาง ทรัพยากรที่ไม่จำเป็นสามารถรอโหลดจนกว่าการเริ่มต้นจะเสร็จสมบูรณ์ได้

หากต้องการแลกเปลี่ยนประสิทธิภาพ ให้พิจารณาสิ่งต่อไปนี้

  • ใช้ไลบรารี Macrobenchmark เพื่อวัดเวลาที่ใช้ในการดำเนินการแต่ละอย่าง และระบุบล็อกที่ใช้เวลานานในการดำเนินการให้เสร็จสมบูรณ์

  • ยืนยันว่าการดำเนินการที่ใช้ทรัพยากรจำนวนมากมีความสำคัญต่อการเริ่มต้นแอป หากการดำเนินการรอได้จนกว่าแอปจะวาดเสร็จสมบูรณ์ ก็จะช่วยลดข้อจำกัดด้านทรัพยากรเมื่อเริ่มต้นได้

  • ตรวจสอบว่าคุณคาดหวังให้การดำเนินการนี้ทำงานเมื่อแอปเริ่มต้น บ่อยครั้งที่ การดำเนินการที่ไม่จำเป็นอาจเรียกใช้จากโค้ดเดิมหรือไลบรารีของบุคคลที่สาม

  • ย้ายการดำเนินการที่ใช้เวลานานไปไว้เบื้องหลัง หากเป็นไปได้ กระบวนการในเบื้องหลัง ยังคงส่งผลต่อการใช้งาน CPU ในระหว่างการเริ่มต้นระบบได้

หลังจากตรวจสอบการดำเนินการอย่างละเอียดแล้ว คุณจะตัดสินใจเลือกข้อแลกเปลี่ยน ระหว่างเวลาที่ใช้ในการโหลดกับความจำเป็นในการรวมไว้ในการเริ่มต้นแอปได้ อย่าลืมพิจารณาถึงความเป็นไปได้ที่จะเกิดการเกิดปัญหาซ้ำหรือการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบ เมื่อแก้ไขเวิร์กโฟลว์ของแอป

เพิ่มประสิทธิภาพและวัดซ้ำจนกว่าคุณจะพอใจกับเวลาเริ่มต้นของ แอป ดูข้อมูลเพิ่มเติมได้ที่ใช้เมตริกเพื่อตรวจหาและวินิจฉัย ปัญหา

วัดและวิเคราะห์เวลาที่ใช้ในการดำเนินการหลักๆ

เมื่อมีร่องรอยการเริ่มต้นแอปที่สมบูรณ์ ให้ดูร่องรอยและวัดเวลา ที่ใช้ในการดำเนินการหลักๆ เช่น bindApplication หรือ activityStart เราขอแนะนำให้ใช้ Perfetto หรือ Android Studio Profilers เพื่อวิเคราะห์การติดตามเหล่านี้

ดูเวลาโดยรวมที่ใช้ในระหว่างการเริ่มต้นแอปเพื่อระบุการดำเนินการที่ทำสิ่งต่อไปนี้

  • ใช้กรอบเวลาขนาดใหญ่และสามารถเพิ่มประสิทธิภาพได้ ทุกมิลลิวินาทีมีค่าใน ประสิทธิภาพ เช่น มองหาเวลาในการวาด Choreographer เวลาในการคอมโพสเริ่มต้น เวลาในการโหลดไลบรารี Binder ธุรกรรม หรือเวลาในการโหลดทรัพยากร หากต้องการเริ่มต้นโดยทั่วไป ให้ดูการดำเนินการทั้งหมดที่ใช้เวลานานกว่า 20 มิลลิวินาที
  • บล็อกเทรดหลัก ดูข้อมูลเพิ่มเติมได้ที่ไปยังส่วนต่างๆ ของรายงาน Systrace
  • ไม่จำเป็นต้องเรียกใช้ระหว่างการเริ่มต้นระบบ
  • รอจนกว่าจะวาดเฟรมแรกเสร็จ

ตรวจสอบร่องรอยแต่ละรายการเพิ่มเติมเพื่อหาช่องโหว่ด้านประสิทธิภาพ

ระบุการดำเนินการที่ใช้ทรัพยากรมากในเทรดหลัก

แนวทางปฏิบัติแนะนำคือหลีกเลี่ยงการดำเนินการที่มีค่าใช้จ่ายสูง เช่น I/O ของไฟล์และการเข้าถึงเครือข่าย ในเทรดหลัก ซึ่งมีความสำคัญไม่แพ้กันในระหว่างการเริ่มต้นแอป เนื่องจากการดำเนินการที่มีค่าใช้จ่ายสูงในเทรดหลักอาจทำให้แอปไม่ตอบสนอง และทำให้การดำเนินการที่สำคัญอื่นๆ ล่าช้า StrictMode.ThreadPolicy ช่วยระบุกรณีที่การดำเนินการที่มีค่าใช้จ่ายสูงเกิดขึ้นในเทรดหลัก แนวทางปฏิบัติที่ดีคือการเปิดใช้ StrictMode ในบิลด์สำหรับแก้ไขข้อบกพร่องเพื่อระบุปัญหาให้เร็วที่สุด ดังที่แสดงในตัวอย่างต่อไปนี้

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()

        ...
        if (BuildConfig.DEBUG)
            StrictMode.setThreadPolicy(
                StrictMode.ThreadPolicy.Builder()
                    .detectAll()
                    .penaltyDeath()
                    .build()
            )
        ...
    }
}

การใช้ StrictMode.ThreadPolicy จะเปิดใช้นโยบายเธรดในการสร้างดีบักทั้งหมด และทำให้แอปขัดข้องเมื่อตรวจพบการละเมิดนโยบายเธรด ซึ่ง ทำให้พลาดการละเมิดนโยบายเธรดได้ยาก

TTID และ TTFD

หากต้องการดูเวลาที่แอปใช้ในการสร้างเฟรมแรก ให้วัดเวลา ในการแสดงผลครั้งแรก (TTID) อย่างไรก็ตาม เมตริกนี้ไม่ได้แสดงถึงเวลาจนกว่าผู้ใช้จะเริ่มโต้ตอบกับแอปเสมอไป เมตริกเวลาจนกว่าจะแสดงผลเต็มรูปแบบ (TTFD) มีประโยชน์มากกว่าในการวัดและเพิ่มประสิทธิภาพเส้นทางโค้ดที่จำเป็นเพื่อให้แอปอยู่ในสถานะที่ใช้งานได้อย่างเต็มที่

ดูกลยุทธ์ในการรายงานเมื่อ UI ของแอปวาดเสร็จสมบูรณ์ได้ที่ปรับปรุงความแม่นยำของเวลาเริ่มต้น

เพิ่มประสิทธิภาพทั้ง TTID และ TTFD เนื่องจากทั้ง 2 อย่างมีความสำคัญในด้านของตนเอง TTID สั้นๆ จะช่วยให้ผู้ใช้เห็นว่าแอปกำลังเปิดตัวจริงๆ การลด TTFD เป็นสิ่งสำคัญที่จะช่วยให้มั่นใจว่าผู้ใช้จะเริ่มโต้ตอบกับ แอปได้อย่างรวดเร็ว

วิเคราะห์สถานะของเธรดโดยรวม

เลือกเวลาเริ่มต้นของแอปและดูส่วนย่อยของเธรดโดยรวม เธรดหลัก ต้องตอบสนองได้ตลอดเวลา

เครื่องมือต่างๆ เช่น Android Studio Profiler และ Perfetto จะแสดงภาพรวมแบบละเอียดของเทรดหลักและระยะเวลาที่ใช้ในแต่ละขั้นตอน ดูข้อมูลเพิ่มเติมเกี่ยวกับการแสดงภาพร่องรอย Perfetto ได้ที่เอกสารประกอบของ UI ของ Perfetto

ระบุช่วงเวลาที่สำคัญซึ่งเธรดหลักอยู่ในสถานะหยุดทำงาน

หากใช้เวลาในการสลีปนานมาก แสดงว่าอาจเป็นผลมาจาก เธรดหลักของแอปที่รอให้งานเสร็จสมบูรณ์ หากคุณมีแอปแบบมัลติเธรด ให้ระบุเธรดที่เธรดหลักกำลังรออยู่ และพิจารณาเพิ่มประสิทธิภาพการดำเนินการเหล่านี้ นอกจากนี้ ยังมีประโยชน์ในการตรวจสอบว่าไม่มีการแย่งชิงล็อกที่ไม่จำเป็นซึ่งทำให้เกิดความล่าช้าในเส้นทางวิกฤต

ลดการบล็อกเทรดหลักและการหยุดทำงานชั่วคราว

มองหาทุกอินสแตนซ์ของเทรดหลักที่เข้าสู่สถานะถูกบล็อก Perfetto และ Studio Profiler จะแสดงสิ่งนี้ด้วยตัวบ่งชี้สีส้มในไทม์ไลน์สถานะของเธรด ระบุการดำเนินการ ตรวจสอบว่าการดำเนินการเหล่านี้เป็นไปตามที่คาดไว้หรือหลีกเลี่ยงได้หรือไม่ และเพิ่มประสิทธิภาพหากจำเป็น

การหยุดทำงานที่เกี่ยวข้องกับ I/O อาจเป็นโอกาสที่ดีในการปรับปรุง กระบวนการอื่นๆ ที่ทำ I/O แม้ว่าจะเป็นแอปที่ไม่เกี่ยวข้อง ก็อาจ แข่งขันกับ I/O ที่แอปยอดนิยมกำลังทำอยู่

ปรับปรุงเวลาเริ่มต้น

หลังจากระบุโอกาสในการเพิ่มประสิทธิภาพแล้ว ให้สํารวจโซลูชันที่เป็นไปได้ เพื่อช่วยปรับปรุงเวลาเริ่มต้น

  • โหลดเนื้อหาแบบเลื่อนและแบบไม่พร้อมกันเพื่อเพิ่มความเร็วของ TTID
  • ลดฟังก์ชันการโทรที่ทำการเรียก Binder หากหลีกเลี่ยงไม่ได้ ให้ตรวจสอบว่าคุณเพิ่มประสิทธิภาพการเรียกเหล่านั้นด้วยการแคชค่าแทน การเรียกซ้ำหรือย้ายงานที่ไม่บล็อกไปยังเธรดเบื้องหลัง
  • หากต้องการให้การเริ่มต้นแอปดูเร็วขึ้น คุณสามารถแสดงสิ่งที่ต้องมีการแสดงผลน้อยที่สุดต่อผู้ใช้โดยเร็วที่สุดจนกว่าหน้าจอส่วนที่เหลือจะโหลดเสร็จ
  • สร้างและเพิ่มโปรไฟล์สตาร์ทอัพ ลงในแอป
  • ใช้ไลบรารีการเริ่มต้นแอปของ Jetpack เพื่อ เพิ่มประสิทธิภาพการเริ่มต้นคอมโพเนนต์ระหว่างการเริ่มต้นแอป

วิเคราะห์ประสิทธิภาพ UI

การเริ่มต้นแอปประกอบด้วยหน้าจอเริ่มต้น (Splash Screen) และเวลาในการโหลดหน้าแรก หากต้องการเพิ่มประสิทธิภาพการเริ่มต้นแอป ให้ตรวจสอบการติดตามเพื่อทำความเข้าใจเวลาที่ใช้ในการวาด UI

จำกัดการทำงานในการเริ่มต้น

บางเฟรมอาจใช้เวลาในการโหลดนานกว่าเฟรมอื่นๆ ซึ่งถือเป็นการวาดภาพที่มีค่าใช้จ่ายสูงสำหรับแอป

หากต้องการเพิ่มประสิทธิภาพการเริ่มต้น ให้ทำดังนี้

  • ให้ความสำคัญกับระยะการจัดองค์ประกอบและเลย์เอาต์ที่ช้า และเลือกระยะเหล่านี้เพื่อปรับปรุง
  • ตรวจสอบคำเตือนแต่ละรายการจาก Perfetto และการแจ้งเตือนจาก Systrace โดยการเพิ่มเหตุการณ์การติดตามที่กำหนดเองเพื่อลดการวาดภาพที่มีค่าใช้จ่ายสูงและความล่าช้า

วัดข้อมูลเฟรม

การวัดข้อมูลเฟรมทำได้หลายวิธี วิธีการเก็บรวบรวมข้อมูลหลัก 5 วิธี มีดังนี้

  • การรวบรวมข้อมูลในเครื่องโดยใช้ dumpsys gfxinfo: เฟรมบางเฟรมที่สังเกตได้ในข้อมูล dumpsys ไม่ได้เป็นสาเหตุที่ทำให้แอปของคุณแสดงผลช้าหรือมีผลกระทบต่อ ผู้ใช้ปลายทาง อย่างไรก็ตาม นี่เป็นตัวชี้วัดที่ดีที่ควรพิจารณาในรอบการเปิดตัวต่างๆ เพื่อทำความเข้าใจแนวโน้มประสิทธิภาพโดยทั่วไป ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ gfxinfo และ framestats เพื่อผสานรวมการวัดประสิทธิภาพ UI เข้ากับแนวทางการทดสอบได้ที่พื้นฐานของการทดสอบแอป Android
  • การเก็บข้อมูลภาคสนามโดยใช้ JankStats: รวบรวมเวลาในการแสดงผลเฟรมจากส่วนที่เฉพาะเจาะจงของแอปด้วยไลบรารี JankStats และบันทึกและวิเคราะห์ข้อมูล
  • ในการทดสอบโดยใช้ Macrobenchmark (Perfetto เบื้องหลัง)
  • Perfetto FrameTimeline: ใน Android 12 (ระดับ API 31) ขึ้นไป คุณสามารถรวบรวมเมตริกไทม์ไลน์เฟรมจากร่องรอยของ Perfetto เพื่อระบุว่างานใดที่ทำให้เฟรมหลุด ซึ่งอาจเป็นขั้นตอนแรกในการวินิจฉัยสาเหตุที่เฟรมหลุด
  • Profiler ของ Android Studio สำหรับการตรวจหาการกระตุก

ตรวจสอบเวลาที่ใช้ในการโหลดกิจกรรมหลัก

กิจกรรมหลักของแอปอาจมีข้อมูลจำนวนมากที่โหลดจากหลายแหล่งที่มา ตรวจสอบ UI ของบ้าน Activity และดูChoreographer#doFrameเหตุการณ์โดยเฉพาะ

  • ใช้ reportFullyDrawn เพื่อรายงานต่อระบบว่าตอนนี้แอปของคุณวาดเสร็จสมบูรณ์แล้วเพื่อวัตถุประสงค์ในการเพิ่มประสิทธิภาพ
  • วัดกิจกรรมและการเปิดแอปโดยใช้ StartupTimingMetric ด้วยไลบรารี Macrobenchmark
  • ดูการดรอปของเฟรม
  • ระบุเลย์เอาต์ที่ใช้เวลานานในการแสดงผลหรือวัด
  • ระบุชิ้นงานที่ใช้เวลาโหลดนาน
  • ระบุองค์ประกอบ UI ที่ไม่จำเป็นซึ่งรวมอยู่ในการจัดองค์ประกอบเริ่มต้น

ลองใช้โซลูชันต่อไปนี้เพื่อเพิ่มประสิทธิภาพเวลาที่ใช้ในการโหลดกิจกรรมหลัก

  • ทำให้การจัดองค์ประกอบเริ่มต้นมีน้ำหนักเบาที่สุดเท่าที่จะเป็นไปได้ ดูข้อมูลเพิ่มเติมได้ที่ประสิทธิภาพของ Jetpack Compose
  • เพิ่ม Tracepoint ที่กำหนดเองเพื่อให้ข้อมูลเพิ่มเติมเกี่ยวกับเฟรมที่หลุดและเลย์เอาต์ที่ซับซ้อน
  • ลดจำนวนและขนาดของทรัพยากรบิตแมปที่โหลดระหว่างการเริ่มต้น ดูข้อมูลเพิ่มเติมได้ที่การเพิ่มประสิทธิภาพรูปภาพบิตแมป
  • หากใช้ Jetpack Compose ให้ลองใช้ การเขียนแบบมีเงื่อนไขเพื่อเลื่อนการโหลดส่วนต่างๆ ของ UI ที่ไม่ ปรากฏขึ้นทันทีเมื่อเปิดแอป เช่น หน้าจอข้อผิดพลาด รายละเอียดที่ไม่บังคับ หรือ แท็บรอง การห่อหุ้มคอมโพเนนต์ที่มีน้ำหนักมากด้วยการตรวจสอบสถานะอย่างง่ายจะช่วยให้คุณหลีกเลี่ยงการเรียกใช้ตรรกะการจัดองค์ประกอบในระหว่างช่วงเวลาเริ่มต้นที่สำคัญได้ ซึ่งจะช่วยให้เลย์เอาต์เริ่มต้นมีน้ำหนักเบา

    var shouldLoad by remember {mutableStateOf(false)}
    
    if (shouldLoad) {
     MyComposable()
    }
    

    โหลด Composable ภายในบล็อกแบบมีเงื่อนไขโดยแก้ไข shouldLoad ดังนี้

    LaunchedEffect(Unit) {
     shouldLoad = true
    }
    

    ซึ่งจะทริกเกอร์การจัดองค์ประกอบใหม่ที่รวมโค้ดภายในบล็อกแบบมีเงื่อนไขในข้อมูลโค้ดแรก

    ดูข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มประสิทธิภาพ Compose ได้ที่ แนวทางปฏิบัติแนะนำ