เวลาเริ่มต้นของแอป

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

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

ทำความเข้าใจสถานะการเริ่มต้นแอปที่แตกต่างกัน

การเปิดตัวแอปสามารถดำเนินการได้ 1 ใน 3 สถานะ ได้แก่ Cold Start, Warm Start หรือ Hot เริ่ม แต่ละสถานะจะมีผลต่อระยะเวลาที่ใช้ในการมองเห็นแอปของคุณ ผู้ใช้รายนั้น ในช่วง Cold Start แอปของคุณจะเริ่มใหม่ตั้งแต่ต้น ในรัฐอื่นๆ ระบบต้องนำแอปที่กำลังทำงานจาก เบื้องหลังไปยังเบื้องหน้า

เราขอแนะนําให้คุณเพิ่มประสิทธิภาพตามสมมติฐานของ Cold Start เสมอ ซึ่งวิธีนี้ช่วยปรับปรุงประสิทธิภาพการทำงานของ Warm Start ได้ด้วยเช่นกัน

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

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

การเริ่มแอปแบบ Cold Start

การเริ่มแอปตั้งแต่ต้นหมายถึงการเริ่มต้นแอปตั้งแต่ต้น ซึ่งหมายความว่า เริ่มต้นนี้ ขั้นตอนของระบบจะสร้างกระบวนการของแอป การเริ่มแอปแบบ Cold Start ในกรณีต่างๆ เช่น แอปของคุณเปิดขึ้นเป็นครั้งแรกนับตั้งแต่เปิดเครื่อง หรือเนื่องจากระบบทำให้แอปหยุดทำงาน

การเริ่มต้นประเภทนี้เป็นความท้าทายที่ยิ่งใหญ่ที่สุดในการลดเวลาในการเริ่มต้น เนื่องจากระบบและแอปมีงานที่ต้องทำมากกว่าสถานะการเปิดใช้งานอื่นๆ

ในช่วงเริ่มต้นของ Cold Start ระบบมีงาน 3 อย่างต่อไปนี้

  1. โหลดและเปิดแอป
  2. แสดงหน้าต่างเริ่มต้นที่ว่างเปล่าของแอปทันทีหลังการเปิดตัว
  3. สร้างขั้นตอนแอป

ทันทีที่ระบบสร้างกระบวนการของแอป กระบวนการของแอปจะรับผิดชอบ สำหรับขั้นตอนถัดไป ได้แก่

  1. สร้างออบเจ็กต์แอป
  2. เปิดชุดข้อความหลัก
  3. สร้างกิจกรรมหลัก
  4. เพิ่มยอดดู
  5. จัดเลย์เอาต์หน้าจอ
  6. ดำเนินการวาดขั้นต้น

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

รูปที่ 1 แสดงวิธีที่ระบบและแอปประมวลผลการส่งต่องานระหว่างกัน อื่นๆ

วันที่
รูปที่ 1 ภาพนำเสนอส่วนสำคัญของ การเปิดตัวแอปที่เย็นๆ

ปัญหาด้านประสิทธิภาพอาจเกิดขึ้นในระหว่างการสร้างแอปและการสร้าง กิจกรรม

การสร้างแอป

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

หากคุณลบล้าง Application.onCreate() ในแอปของคุณเอง ระบบจะ เรียกใช้เมธอด onCreate() ในออบเจ็กต์แอปของคุณ หลังจากนั้นแอปเริ่ม เทรดหลักหรือที่เรียกอีกอย่างว่าเทรด UI และงานในการสร้างเทรดหลัก กิจกรรมหลัก

จากจุดนี้ กระบวนการระดับระบบและแอปจะดำเนินการตาม ในวงจรของแอป

การสร้างกิจกรรม

หลังจากกระบวนการของแอปสร้างกิจกรรมของคุณแล้ว กิจกรรมจะดำเนินการดังนี้ การดำเนินงาน:

  1. เริ่มต้นค่า
  2. เรียกใช้เครื่องมือสร้าง
  3. เรียกใช้เมธอด Callback เช่น Activity.onCreate() เหมาะสม กับสถานะวงจรปัจจุบันของกิจกรรม

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

อุ่นเครื่อง

Warm Start ครอบคลุมการดำเนินการบางส่วนที่เกิดขึ้นในระหว่าง Cold Start ในขณะเดียวกันก็แสดงค่าใช้จ่ายมากกว่าการเริ่มร้อน มีหลายสถานะที่อาจถือได้ว่าเป็น Warm Start เช่น ดังต่อไปนี้:

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

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

เริ่มร้อน

Hot Start ของแอปมีโอเวอร์เฮดต่ำกว่า Cold Start ด้วย Hot Start ระบบจะนํากิจกรรมของคุณไว้ที่เบื้องหน้า หากทุกแอป กิจกรรมยังคงอยู่ในหน่วยความจำ และแอปจะสามารถหลีกเลี่ยงวัตถุซ้ำได้ การเริ่มต้น การขยายเลย์เอาต์ และการแสดงผล

อย่างไรก็ตาม หากระบบลบหน่วยความจำบางส่วนถาวรเพื่อตอบสนองต่อเหตุการณ์การตัดหน่วยความจำ เช่น onTrimMemory() จากนั้นจึงต้องสร้างออบเจ็กต์เหล่านี้ใหม่เพื่อตอบสนอง เหตุการณ์ Hot Start

Hot Start จะแสดงลักษณะการทำงานบนหน้าจอที่เหมือนกับสถานการณ์ Cold Start กระบวนการของระบบจะแสดงหน้าจอว่างเปล่า จนกว่าแอปจะแสดงผล กิจกรรม

วันที่
รูปที่ 2 แผนภาพแสดงสถานะการเริ่มต้นต่างๆ และกระบวนการที่เกี่ยวข้อง แต่ละสถานะจะเริ่มต้นจากเฟรมแรก ที่วาดไว้

วิธีระบุการเริ่มต้นแอปใน Perfetto

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

  1. ใน Perfetto ให้ค้นหาแถวที่มีเมตริกที่ได้มาของ Android App Startups ถ้า คุณไม่เห็น ให้ลองจับภาพการติดตามโดยใช้การติดตามระบบในอุปกรณ์ แอป

    วันที่
    รูปที่ 3ส่วนแบ่งเมตริกที่ได้จากสตาร์ทอัพแอป Android ใน Perfetto
  2. คลิกสไลซ์ที่เกี่ยวข้องและกด m เพื่อเลือกสไลซ์ เครื่องหมายวงเล็บจะปรากฏรอบชิ้นส่วนและระบุระยะเวลาที่ใช้ ระยะเวลาคือ ก็แสดงในแท็บการเลือกปัจจุบันด้วยเช่นกัน

  3. ปักหมุดแถวสตาร์ทอัพของแอป Android โดยคลิกที่ไอคอนหมุด ซึ่งมองเห็นได้เมื่อคุณวางเมาส์ไว้เหนือแถว

  4. เลื่อนไปยังแถวที่มีแอปที่เป็นปัญหา แล้วคลิกเซลล์แรกเพื่อขยาย แถว

  5. ซูมเข้าไปที่เทรดหลัก ซึ่งโดยปกติจะอยู่ที่ด้านบนสุดโดยการกด w (กด s, a, d เพื่อซูมออก เลื่อนไปทางซ้าย และเลื่อนไปทางขวา ตามลำดับ)

    วันที่
    รูปที่ 4ส่วนแบ่งเมตริกที่ได้จากสตาร์ทอัพแอป Android ถัดไป ไปยังเทรดหลักของแอป
  6. ส่วนแบ่งเมตริกที่ได้มาทำให้สามารถดูว่าสิ่งใดรวมอยู่ใน เริ่มต้นแอปเพื่อให้คุณแก้ไขข้อบกพร่องในรายละเอียดต่อไปได้

ใช้เมตริกเพื่อตรวจสอบและปรับปรุงสตาร์ทอัพ

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

ประโยชน์ของการใช้เมตริกสตาร์ทอัพ

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

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

Android Vitals

Android Vitals ช่วยปรับปรุงประสิทธิภาพของแอปได้ด้วยการแจ้งเตือนคุณใน Play Console เมื่อเวลาเริ่มต้นของแอปนานเกินไป

Android Vitals ถือว่าเวลาเริ่มต้นต่อไปนี้สำหรับแอปของคุณมากเกินไป

  • การเริ่มต้นระบบ Cold จะใช้เวลาอย่างน้อย 5 วินาที
  • การเริ่มต้นแบบอบอุ่นจะใช้เวลาอย่างน้อย 2 วินาที
  • การเริ่มต้นระบบ Hot ใช้เวลา 1.5 วินาทีหรือนานกว่านั้น

Android Vitals ใช้เมตริกเวลาที่ใช้ในการแสดงผลครั้งแรก (TTID) สำหรับ ข้อมูลเกี่ยวกับวิธีที่ Google Play รวบรวมข้อมูล Android Vitals โปรดดู เอกสารของคอนโซล

เวลาที่ใช้ในการแสดงผลครั้งแรก

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

TTID จะวัดเป็นค่าเวลาที่แสดงเวลาที่ผ่านไปทั้งหมดที่ มีลําดับเหตุการณ์ต่อไปนี้

  • กำลังเปิดกระบวนการ
  • กำลังเริ่มต้นออบเจ็กต์
  • การสร้างและเริ่มต้นกิจกรรม
  • กำลังขยายเลย์เอาต์
  • การวาดแอปเป็นครั้งแรก

เรียกข้อมูล TTID

หากต้องการค้นหา TTID ให้ค้นหาบรรทัดเอาต์พุตในเครื่องมือบรรทัดคำสั่งของ Logcat ซึ่งมีค่าที่เรียกว่า Displayed ค่านี้จะเป็น TTID และดูคล้ายคลึงกัน กับตัวอย่างต่อไปนี้ โดยที่ TTID เท่ากับ 3s534ms

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

หากต้องการค้นหา TTID ใน Android Studio ให้ปิดใช้ตัวกรองในมุมมอง Logcat จาก เมนูแบบเลื่อนลงของตัวกรอง แล้วหาเวลา Displayed ดังที่แสดงในรูปที่ 5 จำเป็นต้องปิดใช้ตัวกรองเนื่องจากเซิร์ฟเวอร์ระบบ ไม่ใช่แอป จะแสดงบันทึกนี้

วันที่
รูปที่ 5 ปิดใช้ตัวกรองและDisplayedแล้ว ใน Logcat

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

บางครั้งบรรทัด Displayed ในเอาต์พุต Logcat มีช่องเพิ่มเติม สำหรับเวลาทั้งหมด เช่น

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)

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

เราขอแนะนำให้ใช้ Logcat ใน Android Studio แต่หากไม่ได้ใช้ Android Studio คุณยังวัด TTID ได้โดยเรียกใช้แอปด้วย adb Shell คำสั่งเครื่องมือจัดการกิจกรรม ตัวอย่างเช่น

adb [-d|-e|-s <serialNumber>] shell am start -S -W
com.example.app/.MainActivity
-c android.intent.category.LAUNCHER
-a android.intent.action.MAIN

เมตริก Displayed จะปรากฏในเอาต์พุต Logcat เหมือนก่อนหน้านี้ เครื่องชำระเงินของคุณ จะแสดงข้อมูลต่อไปนี้

Starting: Intent
Activity: com.example.app/.MainActivity
ThisTime: 2044
TotalTime: 2044
WaitTime: 2054
Complete

อาร์กิวเมนต์ -c และ -a เป็นแบบไม่บังคับและช่วยให้คุณระบุ <category> ได้ และ <action>

เวลาที่ใช้ในการแสดงผลเต็ม

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

ระบบจะระบุ TTID เมื่อ Choreographer เรียกกิจกรรม onDraw() และเมื่อรู้แล้วเรียกใช้วิธีนี้เป็นครั้งแรก อย่างไรก็ตาม ระบบจะไม่รู้ว่าเมื่อใดที่ควรระบุ TTFD เนื่องจากทุกแอป ก็จะมีการทำงานไม่เหมือนเดิม ในการระบุ TTFD แอปจะต้องส่งสัญญาณไปยังระบบ เมื่อถึงขั้นสุดท้าย

เรียกข้อมูล TTFD

หากต้องการค้นหา TTFD ให้ส่งสัญญาณแจ้งสถานะการดึงทั้งหมดโดยเรียกฟังก์ชัน reportFullyDrawn() ของเมธอด ComponentActivity เมธอด reportFullyDrawn จะรายงานเมื่อมีการสร้างแอปอย่างสมบูรณ์และอยู่ใน TTFD คือเวลาที่ผ่านไปนับจากที่ระบบได้รับการเปิดแอป Intent เวลาที่เรียกใช้ reportFullyDrawn() หากคุณไม่ได้โทร reportFullyDrawn() จะไม่มีการรายงานค่า TTFD

หากต้องการวัด TTFD ให้เรียกใช้ reportFullyDrawn() หลังจากวาด UI เสร็จสมบูรณ์แล้วและ ข้อมูลทั้งหมด ไม่ต้องโทรหา reportFullyDrawn() ก่อนกิจกรรมแรก ก่อนจะถูกวาดและแสดงเป็น "วัดโดยระบบ" จากนั้น ระบบจะรายงานเวลาที่ระบบวัด กล่าวคือ หากคุณเรียกใช้ reportFullyDrawn() ก่อนที่ระบบจะตรวจพบ TTID ระบบจะรายงานทั้ง TTID และ TTFD เป็นค่าเดียวกัน และค่านี้ก็คือค่า TTID

เมื่อคุณใช้ reportFullyDrawn() Logcat จะแสดงเอาต์พุตดังตัวอย่างต่อไปนี้ ตัวอย่างเช่น ซึ่ง TTFD เท่ากับ 1s54 มิลลิวินาที

system_process I/ActivityManager: Fully drawn {package}/.MainActivity: +1s54ms

บางครั้งผลลัพธ์ Logcat จะรวมเวลา total ตามที่พูดคุยไปก่อนหน้านี้ Time to จอแสดงผลเริ่มต้น

หากเวลาที่แสดงช้ากว่าที่คุณต้องการ คุณสามารถลองระบุ จุดคอขวดในกระบวนการเริ่มต้น

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

ปรับปรุงความแม่นยำของช่วงเวลาในการเริ่มต้นใช้งาน

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

เช่น หาก UI มีรายการแบบไดนามิก เช่น RecyclerView หรือรายการแบบ Lazy Loading ส่วนนี้อาจมาจากงานในเบื้องหลังที่เสร็จสมบูรณ์หลังจาก รายการนั้นจะถูกวาดก่อน ดังนั้นหลังจากที่มีการทำเครื่องหมาย UI ว่าวาดอย่างครบถ้วน ในกรณีดังกล่าว ประชากรรายการจะไม่รวมอยู่ในการเปรียบเทียบ

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

FullyDrawnReporter จะไม่เรียกเมธอด reportFullyDrawn() จนกว่าทั้งหมด ผู้รายงานข่าวที่เพิ่มเข้ามาใหม่ จึงได้รับการปล่อยตัว เพิ่มผู้รายงานไปจนถึงกระบวนการเบื้องหลัง เสร็จสมบูรณ์ ช่วงเวลายังรวมถึงระยะเวลาที่ใช้ในการป้อนข้อมูล ในข้อมูลช่วงเวลาเริ่มต้น ซึ่งจะไม่เปลี่ยนแปลงลักษณะการทำงานของแอปสำหรับ แต่สามารถให้ช่วงเวลาของข้อมูลเริ่มต้น รวมถึงเวลาที่ใช้ในการสร้าง รายการ ระบบจะไม่เรียกใช้ reportFullyDrawn() จนกว่างานทั้งหมดจะเสร็จสมบูรณ์ เสร็จสมบูรณ์ ไม่ว่าจะเป็นคำสั่งแบบใดก็ตาม

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

Kotlin

class MainActivity : ComponentActivity() {

    sealed interface ActivityState {
        data object LOADING : ActivityState
        data object LOADED : ActivityState
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            var activityState by remember {
                mutableStateOf(ActivityState.LOADING as ActivityState)
            }
            fullyDrawnReporter.addOnReportDrawnListener {
                activityState = ActivityState.LOADED
            }
            ReportFullyDrawnTheme {
                when(activityState) {
                    is ActivityState.LOADING -> {
                        // Display the loading UI.
                    }
                    is ActivityState.LOADED -> {
                        // Display the full UI.
                    }
                }
            }
            SideEffect {
                lifecycleScope.launch(Dispatchers.IO) {
                    fullyDrawnReporter.addReporter()

                    // Perform the background operation.

                    fullyDrawnReporter.removeReporter()
                }
                lifecycleScope.launch(Dispatchers.IO) {
                    fullyDrawnReporter.addReporter()

                    // Perform the background operation.

                    fullyDrawnReporter.removeReporter()
                }
            }
        }
    }
}

Java

public class MainActivity extends ComponentActivity {
    private FullyDrawnReporter fullyDrawnReporter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        fullyDrawnReporter = getFullyDrawnReporter();
        fullyDrawnReporter.addOnReportDrawnListener(() -> {
            // Trigger the UI update.
            return Unit.INSTANCE;
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                fullyDrawnReporter.addReporter();

                // Do the background work.

               fullyDrawnReporter.removeReporter();
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                fullyDrawnReporter.addReporter();

                // Do the background work.

                fullyDrawnReporter.removeReporter();
            }
        }).start();
    }
}

หากแอปของคุณใช้ Jetpack Compose คุณจะใช้ API ต่อไปนี้เพื่อระบุ สถานะวาดอย่างครบถ้วน:

  • ReportDrawn: บ่งบอกว่า Composable พร้อมใช้งานทันทีสำหรับ การโต้ตอบ
  • ReportDrawnWhen: ใช้ภาคแสดง เช่น list.count > 0 เพื่อ ให้บอกเมื่อ Composable ของคุณพร้อมสำหรับการโต้ตอบ
  • ReportDrawnAfter: ใช้วิธีการระงับ ซึ่งเมื่ออัปเดตแล้ว บ่งบอกว่า Composable ของคุณพร้อมสำหรับการโต้ตอบแล้ว
ระบุจุดคอขวด

คุณสามารถใช้เครื่องมือสร้างโปรไฟล์ CPU ของ Android Studio เพื่อหาจุดคอขวดได้ สำหรับข้อมูลเพิ่มเติม โปรดดูข้อมูลที่หัวข้อตรวจสอบกิจกรรมของ CPU ด้วยเครื่องมือสร้างโปรไฟล์ CPU

คุณยังรับข้อมูลเชิงลึกเกี่ยวกับจุดคอขวดที่อาจเกิดขึ้นผ่านการติดตามในบรรทัดได้ด้วย จากในแอป" และกิจกรรม" onCreate() วิธี หากต้องการทราบเกี่ยวกับการใช้งานในหน้า การติดตามการทำงาน โปรดดูเอกสารประกอบสำหรับฟังก์ชัน Trace และภาพรวม System Tracing

แก้ไขปัญหาที่พบได้ทั่วไป

ส่วนนี้จะกล่าวถึงปัญหาต่างๆ ที่มักส่งผลต่อประสิทธิภาพของการเริ่มต้นแอป ปัญหาเหล่านี้หลักๆ แล้วเกี่ยวข้องกับการเริ่มต้นออบเจ็กต์แอปและกิจกรรม รวมถึง การโหลดหน้าจอ

การเริ่มต้นแอปอย่างหนัก

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

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

ความท้าทายอื่นๆ ในระหว่างการเริ่มต้นแอปรวมถึงเหตุการณ์การเก็บขยะ ที่มีประสิทธิภาพ เป็นจำนวนมาก หรือ I/O ของดิสก์ที่เกิดขึ้นพร้อมกันกับ การเริ่มต้น ซึ่งจะบล็อกกระบวนการเริ่มต้นต่อไป ขยะ ควรพิจารณาเกี่ยวกับรันไทม์ของ Dalvik เป็นพิเศษ Android รันไทม์ (ART) ดำเนินการเก็บขยะพร้อมกัน เพื่อลด ผลกระทบจากการดำเนินการ

วินิจฉัยปัญหา

คุณสามารถใช้การติดตามเมธอดหรือการติดตามแบบอินไลน์เพื่อลองวินิจฉัยปัญหาได้

เมธอดการติดตาม

การเรียกใช้เครื่องมือสร้างโปรไฟล์ CPU จะแสดงว่าcallApplicationOnCreate() เรียกเมธอด com.example.customApplication.onCreate ของคุณขึ้นมา ถ้า เครื่องมือจะแสดงว่าวิธีการเหล่านี้ใช้เวลานานในการดำเนินการให้เสร็จสิ้น สำรวจเพิ่มเติมเพื่อดูว่ามีอะไรเกิดขึ้นบ้าง

การติดตามแบบอินไลน์

ใช้การติดตามในบรรทัดเพื่อตรวจสอบหาสาเหตุที่เป็นไปได้ ซึ่งรวมถึงรายการต่อไปนี้

  • ฟังก์ชัน onCreate() เริ่มต้นของแอป
  • ออบเจ็กต์ Singleton ส่วนกลางที่แอปของคุณเริ่มต้น
  • ดิสก์ I/O, การดีซีเรียลไลซ์ หรือการลูปที่แน่นกระชับที่อาจเกิดขึ้นระหว่าง จุดคอขวด

วิธีแก้ปัญหา

ไม่ว่าปัญหาจะมาจากการเริ่มต้นที่ไม่จำเป็นหรือมาจาก I/O ของดิสก์ คือการเริ่มต้นแบบ Lazy Loading กล่าวคือ เริ่มต้นเฉพาะออบเจ็กต์ที่ ทันที แทนที่จะสร้างวัตถุคงที่ส่วนกลาง ให้ย้ายไปที่ รูปแบบ Singleton ที่แอปจะเริ่มต้นออบเจ็กต์เฉพาะครั้งแรกที่ต้องการ ให้พวกเขา

นอกจากนี้ ให้พิจารณาใช้เฟรมเวิร์กการแทรกทรัพยากร Dependency เช่น Hilt ที่ สร้างออบเจ็กต์และทรัพยากร Dependency เมื่อแทรกเป็นครั้งแรก

หากแอปใช้ผู้ให้บริการเนื้อหาเพื่อเริ่มต้นคอมโพเนนต์ของแอปเมื่อเริ่มต้นระบบ ให้พิจารณาใช้ไลบรารีการเริ่มต้นแอปแทน

การเริ่มต้นกิจกรรมหนัก

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

  • การขยายเลย์เอาต์ขนาดใหญ่หรือซับซ้อนให้พองขึ้น
  • การบล็อกการวาดหน้าจอบนดิสก์หรือ I/O เครือข่าย
  • กำลังโหลดและถอดรหัสบิตแมป
  • กำลังแรสเตอร์วัตถุ VectorDrawable
  • การเริ่มต้นระบบย่อยอื่นๆ ของกิจกรรม

วินิจฉัยปัญหา

ในกรณีนี้ ทั้งการติดตามเมธอดและการติดตามแบบอินไลน์ก็มีประโยชน์เช่นกัน

เมธอดการติดตาม

เมื่อใช้เครื่องมือสร้างโปรไฟล์ CPU โปรดอ่าน Application ของแอป ตัวสร้างคลาสย่อยและเมธอด com.example.customApplication.onCreate()

หากเครื่องมือแสดงว่าวิธีการเหล่านี้ใช้เวลานานในการดำเนินการให้เสร็จสมบูรณ์ สำรวจเพิ่มเติมเพื่อดูว่ามีอะไรเกิดขึ้นบ้าง

การติดตามแบบอินไลน์

ใช้การติดตามในบรรทัดเพื่อตรวจสอบหาสาเหตุที่เป็นไปได้ ซึ่งรวมถึงรายการต่อไปนี้

  • ฟังก์ชัน onCreate() เริ่มต้นของแอป
  • วัตถุแบบ Singleton ส่วนกลางที่เริ่มต้น
  • ดิสก์ I/O, การดีซีเรียลไลซ์ หรือการลูปที่แน่นกระชับที่อาจเกิดขึ้นระหว่าง จุดคอขวด

วิธีแก้ปัญหา

อาจเกิดภาวะคอขวดได้มากมาย แต่ปัญหาที่พบบ่อยและวิธีแก้ไขคือ ดังนี้

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

หน้าจอแนะนำที่กำหนดเอง

คุณอาจเห็นว่ามีการเพิ่มเวลาเพิ่มเติมในช่วงเริ่มต้น หากก่อนหน้านี้คุณใช้ วิธีการต่อไปนี้ในการใช้งานหน้าจอแนะนําที่กําหนดเองใน Android 11 (API ระดับ 30) หรือเก่ากว่า

  • การใช้แอตทริบิวต์ธีม windowDisablePreview เพื่อปิดข้อความเริ่มต้น หน้าจอว่างที่วาดโดยระบบระหว่างการเปิดตัว
  • ใช้ Activity โดยเฉพาะ

ตั้งแต่ Android 12 เป็นต้นไป คุณต้องย้ายข้อมูลไปยัง SplashScreen API API นี้ช่วยให้เปิดเครื่องได้เร็วขึ้น และช่วยให้คุณปรับแต่งหน้าจอแนะนำได้ใน ด้วยวิธีต่อไปนี้

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

ดูรายละเอียดได้ที่คำแนะนำในการย้ายข้อมูลหน้าจอแนะนำ