ผู้ใช้คาดหวังให้แอปโหลดเร็วและตอบสนองได้ดี แอปที่มีเวลาเริ่มต้นช้า ไม่ตรงตามความคาดหวังนี้ และอาจทำให้ผู้ใช้ผิดหวัง แย่แบบนี้ อาจทำให้ผู้ใช้ให้คะแนนแอปของคุณไม่ดีใน 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 แสดงวิธีที่ระบบและแอปประมวลผลการส่งต่องานระหว่างกัน อื่นๆ
![](https://developer.android.com/static/topic/performance/images/cold-launch.png?authuser=19&hl=th)
ปัญหาด้านประสิทธิภาพอาจเกิดขึ้นในระหว่างการสร้างแอปและการสร้าง กิจกรรม
การสร้างแอป
เมื่อแอปของคุณเปิดขึ้น หน้าต่างเริ่มต้นที่ว่างเปล่าจะยังปรากฏอยู่บนหน้าจอจนกว่า ระบบจะวาดแอปให้เสร็จเป็นครั้งแรก ในจุดนี้ ฟิลด์ กระบวนการของระบบจะสลับหน้าต่างเริ่มต้นสำหรับแอปของคุณ ทำให้ผู้ใช้โต้ตอบ กับแอป
หากคุณลบล้าง Application.onCreate()
ในแอปของคุณเอง ระบบจะ
เรียกใช้เมธอด onCreate()
ในออบเจ็กต์แอปของคุณ หลังจากนั้นแอปเริ่ม
เทรดหลักหรือที่เรียกอีกอย่างว่าเทรด UI และงานในการสร้างเทรดหลัก
กิจกรรมหลัก
จากจุดนี้ กระบวนการระดับระบบและแอปจะดำเนินการตาม ในวงจรของแอป
การสร้างกิจกรรม
หลังจากกระบวนการของแอปสร้างกิจกรรมของคุณแล้ว กิจกรรมจะดำเนินการดังนี้ การดำเนินงาน:
- เริ่มต้นค่า
- เรียกใช้เครื่องมือสร้าง
- เรียกใช้เมธอด 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 กระบวนการของระบบจะแสดงหน้าจอว่างเปล่า จนกว่าแอปจะแสดงผล กิจกรรม
![](https://developer.android.com/static/topic/performance/vitals/images/startup-modes-r1.png?authuser=19&hl=th)
วิธีระบุการเริ่มต้นแอปใน Perfetto
ในการแก้ไขข้อบกพร่องของปัญหาการเริ่มต้นแอป คุณควรระบุสิ่งที่รวมอยู่ในอุปกรณ์อย่างชัดเจน ในช่วงเริ่มต้นแอป หากต้องการทราบระยะเริ่มต้นการทำงานของแอปทั้งระยะ Perfetto ให้ทำตามขั้นตอนต่อไปนี้
ใน Perfetto ให้ค้นหาแถวที่มีเมตริกที่ได้มาของ Android App Startups ถ้า คุณไม่เห็น ให้ลองจับภาพการติดตามโดยใช้การติดตามระบบในอุปกรณ์ แอป
วันที่ รูปที่ 3ส่วนแบ่งเมตริกที่ได้จากสตาร์ทอัพแอป Android ใน Perfetto คลิกสไลซ์ที่เกี่ยวข้องและกด m เพื่อเลือกสไลซ์ เครื่องหมายวงเล็บจะปรากฏรอบชิ้นส่วนและระบุระยะเวลาที่ใช้ ระยะเวลาคือ ก็แสดงในแท็บการเลือกปัจจุบันด้วยเช่นกัน
ปักหมุดแถวสตาร์ทอัพของแอป Android โดยคลิกที่ไอคอนหมุด ซึ่งมองเห็นได้เมื่อคุณวางเมาส์ไว้เหนือแถว
เลื่อนไปยังแถวที่มีแอปที่เป็นปัญหา แล้วคลิกเซลล์แรกเพื่อขยาย แถว
ซูมเข้าไปที่เทรดหลัก ซึ่งโดยปกติจะอยู่ที่ด้านบนสุดโดยการกด w (กด s, a, d เพื่อซูมออก เลื่อนไปทางซ้าย และเลื่อนไปทางขวา ตามลำดับ)
วันที่ รูปที่ 4ส่วนแบ่งเมตริกที่ได้จากสตาร์ทอัพแอป Android ถัดไป ไปยังเทรดหลักของแอป ส่วนแบ่งเมตริกที่ได้มาทำให้สามารถดูว่าสิ่งใดรวมอยู่ใน เริ่มต้นแอปเพื่อให้คุณแก้ไขข้อบกพร่องในรายละเอียดต่อไปได้
ใช้เมตริกเพื่อตรวจสอบและปรับปรุงสตาร์ทอัพ
หากต้องการวิเคราะห์ประสิทธิภาพของเวลาเริ่มต้นอย่างเหมาะสม คุณสามารถติดตามเมตริกที่แสดง เวลาที่ใช้ในการเริ่มต้นแอป 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
จำเป็นต้องปิดใช้ตัวกรองเนื่องจากเซิร์ฟเวอร์ระบบ ไม่ใช่แอป
จะแสดงบันทึกนี้
![](https://developer.android.com/static/topic/performance/images/displayed-logcat.png?authuser=19&hl=th)
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 นี้ช่วยให้เปิดเครื่องได้เร็วขึ้น และช่วยให้คุณปรับแต่งหน้าจอแนะนำได้ใน
ด้วยวิธีต่อไปนี้
- ตั้งค่าธีมเพื่อเปลี่ยนรูปลักษณ์ของหน้าจอแนะนำ
- ควบคุมระยะเวลาที่หน้าจอแนะนำจะแสดงด้วย
windowSplashScreenAnimationDuration
- ปรับแต่งภาพเคลื่อนไหวในหน้าจอเริ่มต้น และจัดการ ภาพเคลื่อนไหวสำหรับการปิดหน้าจอแนะนำ
นอกจากนี้ ไลบรารีที่ใช้ร่วมกันยังพอร์ต SplashScreen
API เพื่อเปิดใช้
ความเข้ากันได้แบบย้อนหลังและเพื่อสร้างรูปลักษณ์ที่สอดคล้องกันสำหรับการสาดน้ำ
บนหน้าจอ Android ทุกเวอร์ชัน
ดูรายละเอียดได้ที่คำแนะนำในการย้ายข้อมูลหน้าจอแนะนำ
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- การแสดงผลช้า
- บันทึกเมตริกการเปรียบเทียบระดับมาโคร
- สร้างโปรไฟล์พื้นฐาน{:#creating-profile-rules}