เอกสารนี้ช่วยให้คุณระบุและแก้ไขปัญหาด้านประสิทธิภาพที่สำคัญในแอปได้
ปัญหาด้านประสิทธิภาพที่สำคัญ
มีหลายปัญหาที่อาจทำให้ประสิทธิภาพในแอปไม่ดี แต่ปัญหาที่พบได้ทั่วไปในแอปมีดังนี้
- เวลาในการตอบสนองของการเริ่มต้น
เวลาในการตอบสนองเมื่อเริ่มต้นคือระยะเวลาตั้งแต่แตะไอคอนแอป การแจ้งเตือน หรือจุดแรกเข้าอื่นๆ จนถึงเวลาที่ข้อมูลของผู้ใช้แสดงบนหน้าจอ
ตั้งเป้าหมายเริ่มต้นต่อไปนี้ในแอป
Cold Start ในเวลาน้อยกว่า 500 มิลลิวินาที Cold Start จะเกิดขึ้นเมื่อแอปที่กำลังเปิดตัวไม่ได้อยู่ในหน่วยความจำของระบบ กรณีเช่นนี้เกิดขึ้นเมื่อเป็น การเปิดแอปครั้งแรกนับตั้งแต่รีบูตหรือนับตั้งแต่ผู้ใช้หรือระบบหยุดกระบวนการของแอป
ในทางตรงกันข้าม Warm Start จะเกิดขึ้นเมื่อแอปทำงานอยู่ในเบื้องหลังอยู่แล้ว Cold Start ต้องใช้การทำงานจากระบบมากที่สุด เนื่องจาก ต้องโหลดทุกอย่างจากที่เก็บข้อมูลและเริ่มต้นแอป พยายาม ทำให้ Cold Start ใช้เวลา 500 มิลลิวินาทีหรือน้อยกว่า
เวลาในการตอบสนองที่เปอร์เซ็นไทล์ที่ 95 และ 99 ใกล้เคียงกับเวลาในการตอบสนองตามค่ามัธยฐานมาก เมื่อแอปใช้เวลานานในการเริ่มต้น ผู้ใช้จะได้รับประสบการณ์การใช้งานที่ไม่ดี การสื่อสารระหว่างกระบวนการ (IPC) และ I/O ที่ไม่จำเป็นในระหว่าง เส้นทางวิกฤตของการเริ่มต้นแอปอาจทำให้เกิดการแย่งชิงล็อกและ ทำให้เกิดความไม่สอดคล้องกัน
- การเลื่อนกระตุก
Jank เป็นคำที่อธิบายอาการภาพกระตุกที่เกิดขึ้นเมื่อระบบสร้างและแสดงเฟรมไม่ทันเวลาเพื่อวาดลงบนหน้าจอตามความถี่ที่ขอ 60 Hz ขึ้นไป Jank จะเห็นได้ชัดที่สุดเมื่อ เลื่อนหน้าจอ ซึ่งแทนที่จะเป็นการไหลที่เคลื่อนไหวอย่างราบรื่น แต่กลับมีการสะดุด อาการกระตุก จะเกิดขึ้นเมื่อการเคลื่อนไหวหยุดชั่วคราวระหว่างทางเป็นเวลาอย่างน้อย 1 เฟรม เนื่องจาก แอปใช้เวลานานกว่าในการแสดงเนื้อหามากกว่าระยะเวลาของเฟรมในระบบ
แอปต้องกำหนดเป้าหมายเป็นอัตราการรีเฟรช 90Hz โดยทั่วไปอัตราการแสดงผลคือ 60Hz แต่ในอุปกรณ์รุ่นใหม่ๆ จำนวนมากจะทำงานในโหมด 90Hz ระหว่างการโต้ตอบของผู้ใช้ เช่น การเลื่อน อุปกรณ์บางเครื่องรองรับอัตราที่สูงกว่านี้ถึง 120Hz
หากต้องการดูว่าอุปกรณ์ใช้อัตราการรีเฟรชใดในขณะนั้น ให้เปิดใช้ การวางซ้อนโดยใช้ตัวเลือกสำหรับนักพัฒนาแอป > แสดงอัตราการรีเฟรชในส่วนการแก้ไขข้อบกพร่อง
- การเปลี่ยนฉากที่ไม่ราบรื่น
ซึ่งจะเห็นได้ชัดเจนในระหว่างการโต้ตอบ เช่น การสลับระหว่างแท็บหรือการโหลดกิจกรรมใหม่ การเปลี่ยนฉากประเภทนี้ต้องเป็นภาพเคลื่อนไหวที่ราบรื่นและต้องไม่มีการหน่วงเวลาหรือภาพกะพริบ
- ประสิทธิภาพด้านพลังงาน
การทำงานจะลดการชาร์จแบตเตอรี่ และการทำงานที่ไม่จำเป็นจะลดอายุการใช้งานแบตเตอรี่
การจัดสรรหน่วยความจำซึ่งมาจากการสร้างออบเจ็กต์ใหม่ในโค้ดอาจเป็นสาเหตุที่ทำให้ระบบทำงานหนักมาก เนื่องจากการจัดสรรเหล่านี้ไม่เพียงต้องใช้ความพยายามจาก Android Runtime (ART) เท่านั้น แต่การ ปล่อยออบเจ็กต์เหล่านี้ในภายหลัง (การเก็บขยะ) ยังต้องใช้เวลาและความ พยายามด้วย ทั้งการจัดสรรและการรวบรวมจะเร็วขึ้นและมีประสิทธิภาพมากขึ้น โดยเฉพาะอย่างยิ่งสำหรับออบเจ็กต์ชั่วคราว แม้ว่าแนวทางปฏิบัติแนะนำในอดีตคือการหลีกเลี่ยงการจัดสรรออบเจ็กต์ทุกครั้งที่ทำได้ แต่เราขอแนะนำให้คุณทำสิ่งที่เหมาะกับแอปและสถาปัตยกรรมของคุณมากที่สุด การประหยัดการจัดสรรโดย เสี่ยงต่อการเขียนโค้ดที่ดูแลรักษาไม่ได้ไม่ใช่แนวทางปฏิบัติแนะนำ เนื่องจากความสามารถของ ART
อย่างไรก็ตาม การดำเนินการนี้ต้องใช้ความพยายาม ดังนั้นโปรดทราบว่าการจัดสรรออบเจ็กต์จำนวนมากในลูปด้านในอาจทำให้เกิดปัญหาด้านประสิทธิภาพได้
ระบุปัญหา
เราขอแนะนำเวิร์กโฟลว์ต่อไปนี้เพื่อระบุและแก้ไขปัญหาด้านประสิทธิภาพ
- ระบุและตรวจสอบเส้นทางของผู้ใช้ที่สำคัญต่อไปนี้
- โฟลว์การเริ่มต้นใช้งานทั่วไป รวมถึงจากตัวเรียกใช้และการแจ้งเตือน
- หน้าจอที่ผู้ใช้เลื่อนดูข้อมูล
- การเปลี่ยนระหว่างหน้าจอ
- โฟลว์ที่ทำงานเป็นเวลานาน เช่น การนำทางหรือการเล่นเพลง
- ตรวจสอบสิ่งที่เกิดขึ้นในระหว่างโฟลว์ก่อนหน้าโดยใช้เครื่องมือแก้ไขข้อบกพร่องต่อไปนี้
- Perfetto: ช่วยให้คุณเห็นสิ่งที่เกิดขึ้นในอุปกรณ์ทั้งเครื่อง พร้อมข้อมูลเวลาที่แม่นยำ
- Memory Profiler: ช่วยให้คุณเห็นการจัดสรรหน่วยความจำที่เกิดขึ้นในฮีป
- Simpleperf: แสดงกราฟเปลวไฟของฟังก์ชันที่เรียกใช้ซึ่งใช้ CPU มากที่สุดในช่วงระยะเวลาหนึ่ง เมื่อคุณพบว่ามีบางอย่างใน Systrace ที่ใช้เวลานาน แต่ไม่ทราบสาเหตุ Simpleperf จะให้ข้อมูลเพิ่มเติมได้
การแก้ไขข้อบกพร่องของการทดสอบแต่ละครั้งด้วยตนเองเป็นสิ่งสำคัญอย่างยิ่งในการทำความเข้าใจและแก้ไขข้อบกพร่องเกี่ยวกับประสิทธิภาพเหล่านี้ คุณไม่สามารถแทนที่ขั้นตอนก่อนหน้าด้วยการวิเคราะห์ข้อมูลที่รวบรวมแล้วได้ อย่างไรก็ตาม หากต้องการทราบว่าผู้ใช้เห็นอะไรจริงๆ และระบุว่าเมื่อใดที่อาจเกิดการถดถอย คุณควรตั้งค่าการรวบรวมเมตริกในการทดสอบอัตโนมัติและในภาคสนาม
- ขั้นตอนการเริ่มต้นใช้งาน
- เมตริกฟิลด์: เวลาเริ่มต้นของ Play Console
- การทดสอบในห้องทดลอง: ทดสอบการเริ่มต้นด้วย Macrobenchmark
- Jank
- เมตริกภาคสนาม
- Vitals ของเฟรมใน Play Console: คุณไม่สามารถจำกัดเมตริกให้แคบลงเพื่อเจาะจงเส้นทางของผู้ใช้ที่เฉพาะเจาะจงภายใน Play Console ได้ โดยจะรายงานเฉพาะ Jank โดยรวม ทั่วทั้งแอป
- การวัดที่กำหนดเองด้วย
FrameMetricsAggregator
: คุณใช้FrameMetricsAggregator
เพื่อบันทึกเมตริก Jank ระหว่างเวิร์กโฟลว์ที่เฉพาะเจาะจงได้
- การตรวจในห้องทดลอง
- การเลื่อนด้วย Macrobenchmark
- Macrobenchmark จะรวบรวมเวลาเฟรมโดยใช้คำสั่ง
dumpsys gfxinfo
ที่ครอบคลุมเส้นทางของผู้ใช้คนเดียว ซึ่งเป็นวิธีทำความเข้าใจ ความแปรปรวนของ Jank ในเส้นทางของผู้ใช้ที่เฉพาะเจาะจงRenderTime
เมตริกที่ไฮไลต์ระยะเวลาที่เฟรมใช้ในการวาดมีความสำคัญมากกว่าจำนวนเฟรมที่กระตุกในการระบุการถดถอย หรือการปรับปรุง
- เมตริกภาคสนาม
ปัญหาเกี่ยวกับการยืนยัน App Link
App Link คือ Deep Link ตาม URL ของเว็บไซต์ที่ได้รับการยืนยันแล้วว่าเป็นของเว็บไซต์ของคุณ สาเหตุที่อาจทำให้การยืนยัน App Link ไม่สำเร็จมีดังนี้
- ขอบเขตตัวกรอง Intent: เพิ่ม
autoVerify
ลงในตัวกรอง Intent สำหรับ URL ที่แอปของคุณตอบกลับได้เท่านั้น - การเปลี่ยนโปรโตคอลที่ไม่ได้รับการยืนยัน: การเปลี่ยนเส้นทางฝั่งเซิร์ฟเวอร์และโดเมนย่อยที่ไม่ได้รับการยืนยัน
ถือเป็นความเสี่ยงด้านความปลอดภัยและไม่ผ่านการยืนยัน ซึ่งทำให้ลิงก์ทั้งหมด
autoVerify
ใช้งานไม่ได้ เช่น การเปลี่ยนเส้นทางลิงก์จาก HTTP ไปยัง HTTPS เช่น example.com ไปยัง www.example.com โดยไม่ยืนยันลิงก์ HTTPS อาจทำให้การยืนยันล้มเหลว โปรดยืนยัน App Link โดยการเพิ่มตัวกรอง Intent - ลิงก์ที่ยืนยันไม่ได้: การเพิ่มลิงก์ที่ยืนยันไม่ได้เพื่อวัตถุประสงค์ในการทดสอบอาจ ทำให้ระบบไม่ยืนยัน App Link สำหรับแอปของคุณ
- เซิร์ฟเวอร์ไม่น่าเชื่อถือ: ตรวจสอบว่าเซิร์ฟเวอร์เชื่อมต่อกับแอปไคลเอ็นต์ได้
ตั้งค่าแอปเพื่อการวิเคราะห์ประสิทธิภาพ
การตั้งค่าอย่างเหมาะสมเป็นสิ่งสำคัญเพื่อให้ได้เกณฑ์เปรียบเทียบที่แม่นยำ ทำซ้ำได้ และนำไปใช้ได้จริง จากแอป ทดสอบในระบบที่ใกล้เคียงกับเวอร์ชันที่ใช้งานจริงมากที่สุด ในขณะที่ระงับแหล่งที่มาของสัญญาณรบกวน ส่วนต่อไปนี้แสดงขั้นตอนเฉพาะของ APK และระบบที่คุณสามารถทำเพื่อเตรียมการตั้งค่าการทดสอบ ซึ่งบางขั้นตอนเป็นกรณีการใช้งานที่เฉพาะเจาะจง
Tracepoint
แอปสามารถวัดโค้ดด้วยเหตุการณ์การติดตามที่กำหนดเอง
ในขณะที่บันทึกการติดตาม การติดตามจะทำให้เกิดค่าใช้จ่ายเพิ่มเติมเล็กน้อยประมาณ 5μs ต่อส่วน ดังนั้นจึงไม่ควรวางไว้รอบๆ ทุกเมธอด การติดตามงานที่มีขนาดใหญ่กว่า 0.1 มิลลิวินาทีจะช่วยให้เห็นข้อมูลเชิงลึกที่สำคัญเกี่ยวกับคอขวด
ข้อควรพิจารณาเกี่ยวกับ APK
ตัวแปรการแก้ไขข้อบกพร่องมีประโยชน์ในการแก้ปัญหาและสัญลักษณ์ตัวอย่างสแต็ก
แต่ส่งผลกระทบอย่างรุนแรงต่อประสิทธิภาพ อุปกรณ์ที่ใช้ Android 10 (API
ระดับ 29) ขึ้นไปสามารถใช้ profileable android:shell="true"
ใน
ไฟล์ Manifest เพื่อเปิดใช้การสร้างโปรไฟล์ในบิลด์ที่เผยแพร่
ใช้การกำหนดค่าการลดขนาดโค้ดระดับเวอร์ชันที่ใช้งานจริง ซึ่งอาจส่งผลต่อประสิทธิภาพอย่างมาก ทั้งนี้ขึ้นอยู่กับ ทรัพยากรที่แอปใช้ การกำหนดค่า ProGuard บางอย่างจะนำจุดติดตามออก ดังนั้นโปรดนำกฎเหล่านั้นออกสำหรับการกำหนดค่าที่คุณใช้ทดสอบ
การรวบรวม
คอมไพล์แอปในอุปกรณ์ให้อยู่ในสถานะที่ทราบ โดยทั่วไปคือ speed
เพื่อความง่าย หรือ speed-profile
เพื่อให้ตรงกับประสิทธิภาพของเวอร์ชันที่ใช้งานจริงมากขึ้น
(แม้ว่าวิธีนี้จะต้องวอร์มอัปแอปพลิเคชันและทิ้งโปรไฟล์ หรือ
คอมไพล์โปรไฟล์พื้นฐานของแอป)
ทั้ง speed
และ speed-profile
จะลดปริมาณโค้ดที่ทำงาน
ซึ่งตีความจาก DEX และส่งผลให้ปริมาณการคอมไพล์แบบ Just-In-Time (JIT) ในเบื้องหลังลดลง
ซึ่งอาจทำให้เกิดการรบกวนอย่างมาก speed-profile
จะลดผลกระทบของการโหลดคลาสรันไทม์จาก Dex เท่านั้น
คำสั่งต่อไปนี้จะคอมไพล์แอปพลิเคชันโดยใช้โหมด speed
adb shell cmd package compile -m speed -f com.example.packagename
speed
โหมดการคอมไพล์จะคอมไพล์เมธอดของแอปอย่างสมบูรณ์
speed-profile
โหมดจะคอมไพล์เมธอดและคลาสของแอปตาม
โปรไฟล์ของเส้นทางโค้ดที่ใช้ซึ่งรวบรวมไว้ในระหว่างการใช้งานแอป การรวบรวมโปรไฟล์อย่างสม่ำเสมอและถูกต้องอาจเป็นเรื่องยาก ดังนั้นหากคุณตัดสินใจที่จะใช้โปรไฟล์ ให้ตรวจสอบว่าโปรไฟล์รวบรวมข้อมูลตามที่คุณคาดหวัง โปรไฟล์จะอยู่ในตำแหน่งต่อไปนี้
/data/misc/profiles/ref/[package-name]/primary.prof
ข้อควรพิจารณาเกี่ยวกับระบบ
หากต้องการวัดความแม่นยำระดับต่ำและสูง ให้ปรับเทียบอุปกรณ์ ทำการทดสอบ A/B ในอุปกรณ์เดียวกันและระบบปฏิบัติการเวอร์ชันเดียวกัน ประสิทธิภาพอาจแตกต่างกันอย่างมาก แม้ว่าจะเป็นอุปกรณ์ประเภทเดียวกันก็ตาม
ในอุปกรณ์ที่รูทแล้ว ให้ลองใช้สคริปต์ lockClocks
สำหรับ
Microbenchmarks สคริปต์เหล่านี้จะทำสิ่งต่างๆ ต่อไปนี้
- ตั้งค่าความถี่ของ CPU ให้คงที่
- ปิดใช้คอร์ขนาดเล็กและกำหนดค่า GPU
- ปิดใช้การควบคุมอุณหภูมิ
เราไม่แนะนำให้ใช้lockClocks
สคริปต์สำหรับการทดสอบที่เน้นประสบการณ์ของผู้ใช้
เช่น การเปิดตัวแอป การทดสอบ DoU และการทดสอบ Jank แต่สคริปต์อาจจำเป็นสำหรับ
การลดสัญญาณรบกวนในการทดสอบ Microbenchmark
หากเป็นไปได้ ให้พิจารณาใช้เฟรมเวิร์กการทดสอบ เช่น Macrobenchmark ซึ่งจะช่วยลดสัญญาณรบกวนในการวัดผลและป้องกันการวัดผลที่ไม่ถูกต้อง
การเริ่มต้นแอปช้า: กิจกรรมแทรมโพลีนที่ไม่จำเป็น
กิจกรรมการเปลี่ยนเส้นทางอาจขยายเวลาเริ่มต้นของแอปโดยไม่จำเป็น และคุณควรทราบว่าแอปของคุณกำลังทำเช่นนี้หรือไม่
ดังที่แสดงในตัวอย่างต่อไปนี้
trace หนึ่ง activityStart
ตามด้วยอีก activityStart
ทันที
โดยที่กิจกรรมแรกไม่ได้วาดเฟรมใดๆ
รูปที่ 1 ร่องรอยที่แสดงกิจกรรมแทรมโพลีน
ปัญหานี้อาจเกิดขึ้นได้ทั้งในจุดแรกเข้าของการแจ้งเตือนและจุดแรกเข้าของการเริ่มต้นแอปตามปกติ และคุณมักจะแก้ไขได้ด้วยการปรับโครงสร้างโค้ด ตัวอย่างเช่น หากคุณ ใช้กิจกรรมนี้เพื่อทำการตั้งค่าก่อนที่กิจกรรมอื่นจะทำงาน ให้แยกโค้ดนี้ ออกเป็นคอมโพเนนต์หรือไลบรารีที่นำกลับมาใช้ใหม่ได้
การจัดสรรที่ไม่จำเป็นซึ่งทำให้เกิด GC บ่อยครั้ง
คุณอาจเห็นการเก็บขยะ (GC) เกิดขึ้นบ่อยกว่าที่คาดไว้ใน Systrace
ในตัวอย่างต่อไปนี้ ทุกๆ 10 วินาทีระหว่างการดำเนินการที่ใช้เวลานานจะเป็น ตัวบ่งชี้ว่าแอปอาจจัดสรรโดยไม่จำเป็นแต่สอดคล้องกันเมื่อเวลาผ่านไป
รูปที่ 2 การติดตามที่แสดงช่องว่างระหว่างเหตุการณ์ GC
นอกจากนี้ คุณยังอาจสังเกตเห็นว่า Call Stack ที่เฉพาะเจาะจงทำให้เกิดการจัดสรรส่วนใหญ่เมื่อใช้ Memory Profiler คุณไม่จำเป็นต้องกำจัดการจัดสรรทั้งหมดอย่างจริงจัง เนื่องจากอาจทำให้โค้ดดูแลรักษายากขึ้น แต่ให้เริ่มจากการทำงานกับฮอตสปอตของการจัดสรรแทน
เฟรมที่กระตุก
ไปป์ไลน์กราฟิกค่อนข้างซับซ้อน และอาจมีรายละเอียดบางอย่างในการพิจารณาว่าผู้ใช้จะเห็นเฟรมที่ขาดหายไปหรือไม่ ในบางกรณี แพลตฟอร์มสามารถ "กู้" เฟรมได้โดยใช้การบัฟเฟอร์ อย่างไรก็ตาม คุณสามารถละเลยความแตกต่างส่วนใหญ่ เพื่อระบุเฟรมที่มีปัญหาจากมุมมองของแอป
เมื่อมีการวาดเฟรมโดยที่แอปไม่ต้องทำงานมาก
Choreographer.doFrame()
จุดติดตามจะเกิดขึ้นทุกๆ 16.7 มิลลิวินาทีในอุปกรณ์ที่ทำงานที่ 60 FPS
รูปที่ 3 การติดตามที่แสดงเฟรมเร็วที่เกิดขึ้นบ่อย
หากซูมออกและไปยังส่วนต่างๆ ของการติดตาม คุณอาจเห็นว่าบางครั้งเฟรมใช้เวลานานขึ้นเล็กน้อย แต่ก็ยังถือว่าปกติเนื่องจากเฟรมไม่ได้ใช้เวลานานเกินกว่าเวลาที่กำหนดไว้ที่ 16.7 มิลลิวินาที
รูปที่ 4 การติดตามที่แสดงเฟรมเร็วบ่อยๆ พร้อมการทำงานเป็นช่วงๆ
เมื่อเห็นว่าจังหวะปกติเกิดการหยุดชะงัก นั่นหมายความว่าเฟรมไม่ราบรื่น ดังที่แสดง ในรูปที่ 5
รูปที่ 5 การติดตามที่แสดงเฟรมที่กระตุก
คุณฝึกระบุได้
รูปที่ 6 การติดตามที่แสดงเฟรมที่กระตุกมากขึ้น
ในบางกรณี คุณต้องซูมเข้าไปที่ Tracepoint เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับ
มุมมองที่กำลังขยายหรือสิ่งที่ RecyclerView
กำลังทำ ในกรณีอื่นๆ
คุณอาจต้องตรวจสอบเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการระบุเฟรมที่กระตุกและการแก้ไขข้อบกพร่องของสาเหตุได้ที่การแสดงผลช้า
ข้อผิดพลาดที่พบบ่อยเกี่ยวกับ RecyclerView
การทำให้ข้อมูลสำรองทั้งหมดของ RecyclerView
ไม่ถูกต้องโดยไม่จำเป็นอาจ
ทำให้เวลาในการแสดงผลเฟรมยาวนานและเกิดอาการกระตุก แต่เพื่อลดจำนวนมุมมองที่ต้องอัปเดต ให้ล้างข้อมูลที่มีการเปลี่ยนแปลงเท่านั้น
ดูแสดงข้อมูลแบบไดนามิกเพื่อดูวิธีหลีกเลี่ยงnotifyDatasetChanged()
การเรียกใช้ที่มีค่าใช้จ่ายสูง ซึ่งทำให้เนื้อหาอัปเดตแทนที่จะแทนที่ทั้งหมด
หากไม่รองรับ RecyclerView
ที่ซ้อนกันทั้งหมดอย่างถูกต้อง อาจทำให้ต้องสร้างRecyclerView
ภายในขึ้นมาใหม่ทุกครั้ง RecyclerView
ด้านในที่ซ้อนกันทุกรายการต้องมี RecycledViewPool
เพื่อช่วยให้มั่นใจว่า
สามารถนำมุมมองกลับมาใช้ซ้ำระหว่าง RecyclerView
ด้านในทุกรายการได้
การดึงข้อมูลล่วงหน้าไม่เพียงพอหรือดึงข้อมูลล่วงหน้าไม่ทันเวลาอาจทำให้ การเลื่อนไปที่ด้านล่างของรายการเลื่อนไม่ราบรื่นเมื่อผู้ใช้ต้องรอ ข้อมูลเพิ่มเติมจากเซิร์ฟเวอร์ แม้ว่าในทางเทคนิคแล้วนี่จะไม่ใช่ Jank เนื่องจากไม่มีการพลาดกำหนดเวลาของเฟรม แต่คุณก็ปรับปรุง UX ได้อย่างมากโดยการแก้ไขเวลาและปริมาณของการดึงข้อมูลล่วงหน้าเพื่อให้ผู้ใช้ไม่ต้องรอข้อมูล
แก้ไขข้อบกพร่องของแอป
ต่อไปนี้เป็นวิธีการต่างๆ ในการแก้ไขข้อบกพร่องของประสิทธิภาพแอป ดูภาพรวมของการติดตามระบบและการใช้โปรไฟล์ Android Studio ได้ในวิดีโอต่อไปนี้
แก้ไขข้อบกพร่องของการเริ่มต้นแอปด้วย Systrace
ดูภาพรวมของกระบวนการเริ่มต้นแอปได้ที่เวลาเริ่มต้นของแอป และดูภาพรวมของการติดตามระบบได้ในวิดีโอต่อไปนี้
คุณสามารถแยกประเภทสตาร์ทอัพได้ในขั้นตอนต่อไปนี้
- Cold Startup: เริ่มต้นด้วยการสร้างกระบวนการใหม่โดยไม่มีสถานะที่บันทึกไว้
- การเริ่มต้นแบบอุ่น: สร้างกิจกรรมใหม่ขณะใช้กระบวนการเดิมซ้ำ หรือ สร้างกระบวนการใหม่โดยใช้สถานะที่บันทึกไว้
- การเริ่มต้นแบบด่วน: รีสตาร์ทกิจกรรมและเริ่มต้นที่การขยาย
เราขอแนะนำให้บันทึก Systrace ด้วยแอปการติดตามระบบในอุปกรณ์ สำหรับ Android 10 ขึ้นไป ให้ใช้ Perfetto สำหรับ Android 9 และต่ำกว่า ให้ใช้ Systrace นอกจากนี้ เราขอแนะนำให้ดูไฟล์การติดตามด้วยโปรแกรมดูการติดตาม Perfetto บนเว็บ ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมของการติดตามระบบ
โดยอิงตามสิ่งที่ควรพิจารณาดังนี้
- ตรวจสอบการแย่งชิง: การแข่งขันเพื่อทรัพยากรที่ได้รับการปกป้องโดยจอภาพอาจทำให้เกิด ความล่าช้าอย่างมากในการเริ่มต้นแอป
ธุรกรรม Binder แบบซิงโครนัส: มองหาธุรกรรมที่ไม่จำเป็นในเส้นทางสำคัญของแอป หากธุรกรรมที่จำเป็นมีค่าใช้จ่ายสูง ให้พิจารณาทำงานร่วมกับทีมแพลตฟอร์มที่เกี่ยวข้องเพื่อทำการปรับปรุง
GC พร้อมกัน: ปัญหานี้พบได้ทั่วไปและมีผลกระทบค่อนข้างน้อย แต่หากพบปัญหานี้บ่อยครั้ง ให้ลองตรวจสอบด้วยโปรไฟล์เลอร์หน่วยความจำของ Android Studio
I/O: ตรวจสอบ I/O ที่ดำเนินการระหว่างการเริ่มต้น และมองหาการหยุดทำงานเป็นเวลานาน
กิจกรรมสำคัญในเธรดอื่นๆ: กิจกรรมเหล่านี้อาจรบกวนเธรด UI ดังนั้นโปรดระวังงานในเบื้องหลังระหว่างการเริ่มต้น
เราขอแนะนำให้เรียกใช้ reportFullyDrawn
เมื่อการเริ่มต้นเสร็จสมบูรณ์จากมุมมองของแอปเพื่อปรับปรุงการรายงานเมตริกการเริ่มต้นแอป ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ reportFullyDrawn
ได้ที่ส่วนเวลา
ในการแสดงผลทั้งหมด
คุณสามารถดึงเวลาเริ่มต้นที่กำหนดโดย RFD ผ่านตัวประมวลผลการติดตาม Perfetto
และจะมีการปล่อยเหตุการณ์การติดตามที่ผู้ใช้มองเห็น
ใช้การติดตามระบบในอุปกรณ์
คุณสามารถใช้แอปที่ระดับระบบที่เรียกว่าการติดตามระบบเพื่อบันทึกการติดตามระบบในอุปกรณ์ แอปนี้ช่วยให้คุณบันทึกร่องรอยจากอุปกรณ์ได้โดยไม่ต้องเสียบปลั๊กหรือเชื่อมต่อกับ adb
ใช้เครื่องมือสร้างโปรไฟล์หน่วยความจำของ Android Studio
คุณใช้ Android Studio Memory Profiler เพื่อตรวจสอบแรงกดดันด้านหน่วยความจำ ที่อาจเกิดจากการรั่วไหลของหน่วยความจำหรือรูปแบบการใช้งานที่ไม่ดีได้ ซึ่งจะแสดงภาพรวมแบบเรียลไทม์ของการจัดสรรออบเจ็กต์
คุณแก้ไขปัญหาหน่วยความจำในแอปได้โดยทำตามข้อมูลจากการใช้ เครื่องมือสร้างโปรไฟล์หน่วยความจำเพื่อติดตามสาเหตุและความถี่ในการเกิด GC
หากต้องการสร้างโปรไฟล์หน่วยความจำของแอป ให้ทำตามขั้นตอนต่อไปนี้
ตรวจหาปัญหาเกี่ยวกับหน่วยความจำ
บันทึกเซสชันการจัดโปรไฟล์หน่วยความจำของเส้นทางของผู้ใช้ที่คุณต้องการโฟกัส มองหาจำนวนออบเจ็กต์ที่เพิ่มขึ้นตามที่แสดงในรูปที่ 7 ซึ่งในที่สุด จะทำให้เกิด GC ตามที่แสดงในรูปที่ 8
รูปที่ 7 เพิ่มจำนวนออบเจ็กต์
รูปที่ 8 การเก็บขยะ
หลังจากระบุเส้นทางของผู้ใช้ที่เพิ่มแรงกดดันด้านหน่วยความจำแล้ว ให้วิเคราะห์ หาสาเหตุที่ทำให้เกิดแรงกดดันด้านหน่วยความจำ
วินิจฉัยจุดที่เกิดแรงกดดันด้านหน่วยความจำ
เลือกช่วงในไทม์ไลน์เพื่อแสดงภาพทั้งการจัดสรรและ ขนาดแบบตื้น ดังที่แสดงในรูปที่ 9
รูปที่ 9 ค่าสำหรับ Allocations และ Shallow Size
คุณจัดเรียงข้อมูลนี้ได้หลายวิธี ตัวอย่างต่อไปนี้แสดงให้เห็นว่ามุมมองแต่ละมุมมองช่วยวิเคราะห์ปัญหาได้อย่างไร
จัดเรียงตามคลาส: มีประโยชน์เมื่อคุณต้องการค้นหาคลาสที่ สร้างออบเจ็กต์ที่แคชหรือนำกลับมาใช้ใหม่จากพูลหน่วยความจำ
ตัวอย่างเช่น หากคุณเห็นแอปสร้างออบเจ็กต์ 2,000 รายการของคลาสที่ชื่อ "Vertex" ทุกวินาที ระบบจะเพิ่มจำนวนการจัดสรร 2,000 รายการ ทุกวินาที และคุณจะเห็นเมื่อจัดเรียงตามคลาส หากต้องการนำออบเจ็กต์เหล่านี้กลับมาใช้ใหม่เพื่อหลีกเลี่ยงการสร้างขยะ ให้ใช้พูลหน่วยความจำ
จัดเรียงตาม Callstack: มีประโยชน์เมื่อคุณต้องการค้นหาตำแหน่งที่มี Hotpath ซึ่งมีการจัดสรรหน่วยความจำ เช่น ภายในลูปหรือภายในฟังก์ชันที่เฉพาะเจาะจงซึ่งทำงานด้านการจัดสรรเป็นจำนวนมาก
ขนาดแบบตื้น: ติดตามเฉพาะหน่วยความจำของออบเจ็กต์เอง ซึ่งมีประโยชน์ สำหรับการติดตามคลาสอย่างง่ายที่ประกอบด้วยค่าดั้งเดิมเป็นส่วนใหญ่เท่านั้น
ขนาดที่เก็บไว้: แสดงหน่วยความจำทั้งหมดเนื่องจากออบเจ็กต์และการอ้างอิง ที่ออบเจ็กต์อ้างอิงเท่านั้น ซึ่งมีประโยชน์ในการติดตามแรงดันหน่วยความจำเนื่องจากออบเจ็กต์ที่ซับซ้อน หากต้องการรับค่านี้ ให้ทำการดัมพ์หน่วยความจำทั้งหมด ตามที่แสดงในรูปที่ 10 และเพิ่มขนาดที่เก็บไว้เป็นคอลัมน์ตามที่แสดงในรูปที่ 11
รูปที่ 10 การทิ้งหน่วยความจำทั้งหมด
รูปที่ 11 คอลัมน์ขนาดที่คงไว้
วัดผลกระทบของการเพิ่มประสิทธิภาพ
GC จะชัดเจนขึ้นและวัดผลกระทบของการเพิ่มประสิทธิภาพหน่วยความจำได้ง่ายขึ้น เมื่อการเพิ่มประสิทธิภาพช่วยลดแรงกดดันด้านหน่วยความจำ คุณจะเห็น GC น้อยลง
หากต้องการวัดผลกระทบของการเพิ่มประสิทธิภาพ ให้วัด เวลาที่ใช้ระหว่าง GC ในไทม์ไลน์ของโปรไฟล์เลอร์ จากนั้นคุณจะเห็นว่าเวลาที่ใช้ระหว่าง GC จะนานขึ้น
ผลกระทบขั้นสุดท้ายของการปรับปรุงหน่วยความจำมีดังนี้
- การปิดระบบเนื่องจากหน่วยความจำไม่เพียงพอมีแนวโน้มที่จะลดลงหากแอปไม่ได้ ใช้หน่วยความจำจนเต็มอยู่ตลอดเวลา
- การมี GC น้อยลงจะช่วยปรับปรุงเมตริกความกระตุก โดยเฉพาะใน P99 เนื่องจาก GC ทำให้เกิดการแย่งชิง CPU ซึ่งอาจทำให้ระบบเลื่อนงานการแสดงผลออกไปในขณะที่ GC กำลังทำงาน
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- การวิเคราะห์และการเพิ่มประสิทธิภาพการเริ่มต้นแอป {:#app-startup-analysis-optimization}
- เฟรมที่ค้าง
- เขียน Macrobenchmark