การเริ่มต้นแอปแสดงถึงความประทับใจแรกของผู้ใช้ที่มีต่อแอป และผู้ใช้ไม่ชอบรอ ดังนั้นคุณต้องตรวจสอบว่าแอปของคุณเริ่มทำงานได้อย่างรวดเร็ว หากต้องการแสดงให้คุณเห็น ว่าทีมพัฒนาแอปในชีวิตจริงค้นหาและวินิจฉัยปัญหาเกี่ยวกับการเริ่มต้นแอปของตนอย่างไร นี่คือสิ่งที่ทีม Gmail Wear OS ทำ
ทีม Gmail Wear OS ได้พยายามเพิ่มประสิทธิภาพ โดยมุ่งเน้นเป็นพิเศษ ที่ประสิทธิภาพการเริ่มต้นแอปและการแสดงผลรันไทม์ เพื่อให้เป็นไปตามเกณฑ์ประสิทธิภาพของแอปของทีม อย่างไรก็ตาม แม้ว่าคุณจะไม่มีเกณฑ์ที่เฉพาะเจาะจงในการ กำหนดเป้าหมาย แต่ก็มักจะมีช่องทางในการปรับปรุงการเริ่มต้นแอปอยู่เสมอ หากคุณใช้เวลา ในการตรวจสอบ
บันทึกการติดตามและดูการเริ่มต้นแอป
หากต้องการเริ่มวิเคราะห์ ให้บันทึกการติดตามที่มี การเริ่มต้นแอปเพื่อตรวจสอบอย่างละเอียดใน Perfetto หรือ Android Studio กรณีศึกษา นี้ใช้ Perfetto เนื่องจากจะแสดงให้เห็นสิ่งที่เกิดขึ้นในระบบ ของอุปกรณ์ นอกเหนือจากแอปของคุณ เมื่ออัปโหลดการติดตามใน Perfetto การติดตามจะมีลักษณะดังนี้

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

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

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

Runnable
ถึง Running
เพื่อให้ทราบเบื้องต้นว่ามีการแย่งชิง CPU
มากน้อยเพียงใดยิ่งอัตราส่วนของเวลาในสถานะ Runnable
ต่อเวลาในสถานะ Running
สูงขึ้น
ก็ยิ่งมีแนวโน้มที่จะเกิดการแย่งชิง CPU เมื่อตรวจสอบปัญหาด้านประสิทธิภาพด้วยวิธีนี้ ให้มุ่งเน้นที่เฟรมที่ทำงานนานที่สุดก่อน แล้วค่อยๆ ดูเฟรมที่ทำงานสั้นลง
เมื่อวิเคราะห์เวลาที่ใช้ในRunnable
สถานะ ให้พิจารณาฮาร์ดแวร์ของอุปกรณ์
เนื่องจากแอปที่แสดงทำงานบนอุปกรณ์ที่สวมใส่ได้ซึ่งมี CPU 2 ตัว เราจึงคาดว่าเวลาที่ใช้ในสถานะ Runnable
จะนานขึ้น และ CPU จะมีการแย่งชิงกับกระบวนการอื่นๆ มากขึ้นกว่าในกรณีที่เราดูอุปกรณ์ที่มี CPU มากกว่า
แม้ว่าแอปโทรศัพท์ทั่วไปจะใช้เวลาในสถานะ Runnable
นานกว่าที่คาดไว้ แต่ก็อาจเข้าใจได้ในบริบทของอุปกรณ์ที่สวมใส่ได้
เวลาที่ใช้ใน OpenDexFilesFromOat*
ตอนนี้ให้ตรวจสอบเวลาที่ใช้ใน OpenDexFilesFromOat*
ในการติดตาม เหตุการณ์นี้จะเกิดขึ้นพร้อมกับสไลซ์ bindApplication
สไลซ์นี้แสดงเวลาที่ใช้ในการอ่านไฟล์ DEX ของแอปพลิเคชัน
ธุรกรรมสมุดบัญชีที่ถูกบล็อก
จากนั้นตรวจสอบธุรกรรมของ Binder ธุรกรรม Binder แสดงถึงการเรียกใช้ระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ ในกรณีนี้ แอป (ไคลเอ็นต์) จะเรียกใช้ระบบ Android (เซิร์ฟเวอร์) ด้วย binder transaction
และเซิร์ฟเวอร์จะตอบกลับด้วย binder
reply
ตรวจสอบว่าแอปไม่ได้ทำธุรกรรม Binder ที่ไม่จำเป็น
ในระหว่างการเริ่มต้น เนื่องจากจะเพิ่มความเสี่ยงของการแย่งชิง CPU หากทำได้ ให้
เลื่อนงานที่เกี่ยวข้องกับการเรียก Binder ไปเป็นหลังจากช่วงเริ่มต้นของแอป หากคุณต้องทำธุรกรรม Binder โปรดตรวจสอบว่าธุรกรรมดังกล่าวใช้เวลาไม่นานกว่าอัตราการรีเฟรช Vsync ของอุปกรณ์
ธุรกรรมการผูกครั้งแรกซึ่งมักจะเกิดขึ้นพร้อมกับActivityThreadMain
ดูเหมือนจะใช้เวลานานพอสมควรในกรณีนี้ หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่อาจเกิดขึ้น ให้ทำตามขั้นตอนต่อไปนี้
- หากต้องการดูการตอบกลับของ Binder ที่เชื่อมโยงและดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดลําดับความสําคัญของธุรกรรม Binder ให้คลิกส่วนธุรกรรม Binder ที่ สนใจ
หากต้องการดูการตอบกลับของ Binder ให้ไปที่แผงการเลือกปัจจุบัน แล้วคลิก การตอบกลับของ Binder ในส่วนเธรดที่ติดตาม ฟิลด์เธรด ยังบอกเธรดที่การตอบกลับของ Binder เกิดขึ้นด้วย หากคุณต้องการ ไปยังเธรดนั้นด้วยตนเอง โดยจะอยู่ในกระบวนการที่แตกต่างกัน เส้นจะปรากฏขึ้น ซึ่งเชื่อมต่อธุรกรรมของ Binder กับการตอบกลับ
รูปที่ 5 ระบุธุรกรรม Binder ที่เกิดขึ้นระหว่างการเริ่มต้นแอปและประเมินว่าคุณสามารถเลื่อนธุรกรรมเหล่านั้นได้หรือไม่ หากต้องการดูว่าเซิร์ฟเวอร์ระบบจัดการธุรกรรม Binder นี้อย่างไร ให้ปักหมุดเธรด CPU 0 และ CPU 1 ไว้ที่ด้านบนของหน้าจอ
ค้นหากระบวนการของระบบที่จัดการการตอบกลับ Binder โดยค้นหา Slice ที่มีชื่อเธรดการตอบกลับ Binder ซึ่งในกรณีนี้คือ "Binder:687_11 [2542]" คลิกกระบวนการของระบบที่เกี่ยวข้องเพื่อดูข้อมูลเพิ่มเติม เกี่ยวกับธุรกรรมการผูก
ดูที่กระบวนการของระบบที่เชื่อมโยงกับธุรกรรม Binder ที่ สนใจซึ่งเกิดขึ้นใน CPU 0

Runnable (Preempted)
ซึ่งบ่งบอกว่าระบบ
ทำงานช้าลงสถานะสิ้นสุดระบุว่า Runnable (Preempted)
ซึ่งหมายความว่ากระบวนการ
ล่าช้าเนื่องจาก CPU กำลังทำอย่างอื่น หากต้องการดูว่าอะไรทำให้เกิดการขัดจังหวะ ให้ขยายแถวเหตุการณ์ Ftrace ในแท็บ Ftrace
Events ที่พร้อมใช้งาน ให้เลื่อนดูและค้นหาเหตุการณ์ที่เกี่ยวข้อง
กับเธรด Binder ที่สนใจ "Binder:687_11 [2542]" ในช่วงเวลาที่ระบบขัดจังหวะกระบวนการของระบบ มีเหตุการณ์เซิร์ฟเวอร์ของระบบ 2 รายการที่รวมอาร์กิวเมนต์ "decon" ซึ่งหมายความว่าเหตุการณ์ดังกล่าวเกี่ยวข้องกับตัวควบคุมการแสดงผล ซึ่งฟังดูสมเหตุสมผลเนื่องจากตัวควบคุมการแสดงผลจะวางเฟรมบนหน้าจอ ซึ่งเป็นงานที่สำคัญ ในกรณีนี้ ให้ปล่อยกิจกรรมไว้ตามเดิม

กิจกรรม JIT
หากต้องการตรวจสอบกิจกรรมการคอมไพล์แบบทันที
(JIT)
ให้ขยายกระบวนการที่เป็นของแอป ค้นหาแถว "Jit thread pool" 2 แถว
แล้วปักหมุดไว้ที่ด้านบนของมุมมอง เนื่องจากแอปนี้ได้รับประโยชน์จากโปรไฟล์พื้นฐานในระหว่างการเริ่มต้นแอป
จึงมีกิจกรรม JIT น้อยมากจนกว่าจะมีการวาดเฟรมแรก ซึ่งระบุโดย
การสิ้นสุดการเรียกใช้ Choreographer.doFrame
ครั้งแรก อย่างไรก็ตาม โปรดสังเกตสาเหตุของการเริ่มต้นที่ช้า
JIT compiling void
ซึ่งบ่งชี้ว่ากิจกรรมของระบบที่เกิดขึ้น
ระหว่าง Tracepoint ที่ติดป้ายกำกับ Application creation
ทำให้เกิดกิจกรรม JIT ในเบื้องหลังจำนวนมาก หากต้องการแก้ไขปัญหานี้ ให้เพิ่มเหตุการณ์ที่เกิดขึ้นหลังจากวาดเฟรมแรกไม่นานลงใน Baseline Profile โดยขยายการรวบรวมโปรไฟล์ไปยังจุดที่แอปพร้อมใช้งาน ในหลายๆ กรณี คุณสามารถ
ทำได้โดยการเพิ่มบรรทัดที่ส่วนท้ายของการรวบรวม Baseline Profile
การทดสอบ Macrobenchmark ที่รอให้วิดเจ็ต UI ที่เฉพาะเจาะจงปรากฏบน
หน้าจอ ซึ่งบ่งบอกว่าหน้าจอมีข้อมูลครบถ้วนแล้ว

ผลลัพธ์
ทีม Gmail สำหรับ Wear OS จึงได้ทำการปรับปรุงต่อไปนี้จากการวิเคราะห์นี้
- เนื่องจากสังเกตเห็นการแย่งชิงทรัพยากรระหว่างการเริ่มต้นแอปเมื่อดูกิจกรรมของ CPU จึงได้แทนที่ภาพเคลื่อนไหวของวงกลมหมุนที่ใช้เพื่อ ระบุว่าแอปกำลังโหลดด้วยรูปภาพแบบคงที่เพียงรูปเดียว นอกจากนี้ ยัง ยืดเวลาหน้าจอเริ่มต้นเพื่อเลื่อนสถานะการสั่นไหว ซึ่งเป็นสถานะหน้าจอที่ 2 ที่ใช้เพื่อระบุว่าแอปกำลังโหลด เพื่อเพิ่มทรัพยากร CPU ซึ่งช่วยปรับปรุงเวลาในการตอบสนองของการเริ่มต้นแอปได้ 50%
- จากการดูเวลาที่ใช้ใน
OpenDexFilesFromOat*
และกิจกรรม JIT ทำให้ทีมได้เปิดใช้การเขียนซ้ำ R8 ของโปรไฟล์พื้นฐาน ซึ่งช่วย ลดเวลาในการตอบสนองเริ่มต้นของแอปได้ 20%
ต่อไปนี้คือเคล็ดลับบางส่วนจากทีมเกี่ยวกับวิธีวิเคราะห์ประสิทธิภาพของแอปอย่างมีประสิทธิภาพ
- ตั้งค่ากระบวนการต่อเนื่องที่สามารถรวบรวมการติดตามและ ผลลัพธ์ได้โดยอัตโนมัติ ลองตั้งค่าการติดตามอัตโนมัติสำหรับแอปโดยใช้การเปรียบเทียบ
- ใช้การทดสอบ A/B สำหรับการเปลี่ยนแปลงที่คุณคิดว่าจะช่วยปรับปรุงสิ่งต่างๆ และปฏิเสธการเปลี่ยนแปลงเหล่านั้นหากไม่เป็นไปตามที่คาดไว้ คุณสามารถวัดประสิทธิภาพในสถานการณ์ต่างๆ ได้โดยใช้ไลบรารี Macrobenchmark
ดูข้อมูลเพิ่มเติมได้ที่แหล่งข้อมูลต่อไปนี้
- ประสิทธิภาพ: การใช้การสร้างโปรไฟล์แบบสุ่มตัวอย่างด้วย Systrace - MAD Skills
- ประสิทธิภาพ: การบันทึกการติดตามของ Profiler - MAD Skills