ภาพรวมการวัดประสิทธิภาพแอป

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

ปัญหาด้านประสิทธิภาพที่สำคัญ

มีหลายปัญหาที่อาจทำให้ประสิทธิภาพในแอปไม่ดี แต่ปัญหาที่พบได้ทั่วไปในแอปมีดังนี้

เวลาในการตอบสนองของการเริ่มต้น

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

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

  • 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

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

ระบุปัญหา

เราขอแนะนำเวิร์กโฟลว์ต่อไปนี้เพื่อระบุและแก้ไขปัญหาด้านประสิทธิภาพ

  1. ระบุและตรวจสอบเส้นทางของผู้ใช้ที่สำคัญต่อไปนี้
    • โฟลว์การเริ่มต้นใช้งานทั่วไป รวมถึงจากตัวเรียกใช้และการแจ้งเตือน
    • หน้าจอที่ผู้ใช้เลื่อนดูข้อมูล
    • การเปลี่ยนระหว่างหน้าจอ
    • โฟลว์ที่ทำงานเป็นเวลานาน เช่น การนำทางหรือการเล่นเพลง
  2. ตรวจสอบสิ่งที่เกิดขึ้นในระหว่างโฟลว์ก่อนหน้าโดยใช้เครื่องมือแก้ไขข้อบกพร่องต่อไปนี้
    • Perfetto: ช่วยให้คุณเห็นสิ่งที่เกิดขึ้นในอุปกรณ์ทั้งเครื่อง พร้อมข้อมูลเวลาที่แม่นยำ
    • Memory Profiler: ช่วยให้คุณเห็นการจัดสรรหน่วยความจำที่เกิดขึ้นในฮีป
    • Simpleperf: แสดงกราฟเปลวไฟของฟังก์ชันที่เรียกใช้ซึ่งใช้ CPU มากที่สุดในช่วงระยะเวลาหนึ่ง เมื่อคุณพบว่ามีบางอย่างใน Systrace ที่ใช้เวลานาน แต่ไม่ทราบสาเหตุ Simpleperf จะให้ข้อมูลเพิ่มเติมได้

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

  • ขั้นตอนการเริ่มต้นใช้งาน
  • Jank
    • เมตริกภาคสนาม
      • Vitals ของเฟรมใน Play Console: คุณไม่สามารถจำกัดเมตริกให้แคบลงเพื่อเจาะจงเส้นทางของผู้ใช้ที่เฉพาะเจาะจงภายใน Play Console ได้ โดยจะรายงานเฉพาะ Jank โดยรวม ทั่วทั้งแอป
      • การวัดที่กำหนดเองด้วย FrameMetricsAggregator: คุณใช้ FrameMetricsAggregator เพื่อบันทึกเมตริก Jank ระหว่างเวิร์กโฟลว์ที่เฉพาะเจาะจงได้
    • การตรวจในห้องทดลอง
      • การเลื่อนด้วย Macrobenchmark
      • Macrobenchmark จะรวบรวมเวลาเฟรมโดยใช้คำสั่ง dumpsys gfxinfo ที่ครอบคลุมเส้นทางของผู้ใช้คนเดียว ซึ่งเป็นวิธีทำความเข้าใจ ความแปรปรวนของ Jank ในเส้นทางของผู้ใช้ที่เฉพาะเจาะจง RenderTime เมตริกที่ไฮไลต์ระยะเวลาที่เฟรมใช้ในการวาดมีความสำคัญมากกว่าจำนวนเฟรมที่กระตุกในการระบุการถดถอย หรือการปรับปรุง

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 ทันที โดยที่กิจกรรมแรกไม่ได้วาดเฟรมใดๆ

alt_text รูปที่ 1 ร่องรอยที่แสดงกิจกรรมแทรมโพลีน

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

การจัดสรรที่ไม่จำเป็นซึ่งทำให้เกิด GC บ่อยครั้ง

คุณอาจเห็นการเก็บขยะ (GC) เกิดขึ้นบ่อยกว่าที่คาดไว้ใน Systrace

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

alt_text รูปที่ 2 การติดตามที่แสดงช่องว่างระหว่างเหตุการณ์ GC

นอกจากนี้ คุณยังอาจสังเกตเห็นว่า Call Stack ที่เฉพาะเจาะจงทำให้เกิดการจัดสรรส่วนใหญ่เมื่อใช้ Memory Profiler คุณไม่จำเป็นต้องกำจัดการจัดสรรทั้งหมดอย่างจริงจัง เนื่องจากอาจทำให้โค้ดดูแลรักษายากขึ้น แต่ให้เริ่มจากการทำงานกับฮอตสปอตของการจัดสรรแทน

เฟรมที่กระตุก

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

เมื่อมีการวาดเฟรมโดยที่แอปไม่ต้องทำงานมาก Choreographer.doFrame() จุดติดตามจะเกิดขึ้นทุกๆ 16.7 มิลลิวินาทีในอุปกรณ์ที่ทำงานที่ 60 FPS

alt_text รูปที่ 3 การติดตามที่แสดงเฟรมเร็วที่เกิดขึ้นบ่อย

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

alt_text รูปที่ 4 การติดตามที่แสดงเฟรมเร็วบ่อยๆ พร้อมการทำงานเป็นช่วงๆ

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

alt_text รูปที่ 5 การติดตามที่แสดงเฟรมที่กระตุก

คุณฝึกระบุได้

alt_text รูปที่ 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

หากต้องการสร้างโปรไฟล์หน่วยความจำของแอป ให้ทำตามขั้นตอนต่อไปนี้

  1. ตรวจหาปัญหาเกี่ยวกับหน่วยความจำ

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

    alt_text รูปที่ 7 เพิ่มจำนวนออบเจ็กต์

    alt_text รูปที่ 8 การเก็บขยะ

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

  2. วินิจฉัยจุดที่เกิดแรงกดดันด้านหน่วยความจำ

    เลือกช่วงในไทม์ไลน์เพื่อแสดงภาพทั้งการจัดสรรและ ขนาดแบบตื้น ดังที่แสดงในรูปที่ 9

    alt_text รูปที่ 9 ค่าสำหรับ Allocations และ Shallow Size

    คุณจัดเรียงข้อมูลนี้ได้หลายวิธี ตัวอย่างต่อไปนี้แสดงให้เห็นว่ามุมมองแต่ละมุมมองช่วยวิเคราะห์ปัญหาได้อย่างไร

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

      ตัวอย่างเช่น หากคุณเห็นแอปสร้างออบเจ็กต์ 2,000 รายการของคลาสที่ชื่อ "Vertex" ทุกวินาที ระบบจะเพิ่มจำนวนการจัดสรร 2,000 รายการ ทุกวินาที และคุณจะเห็นเมื่อจัดเรียงตามคลาส หากต้องการนำออบเจ็กต์เหล่านี้กลับมาใช้ใหม่เพื่อหลีกเลี่ยงการสร้างขยะ ให้ใช้พูลหน่วยความจำ

    • จัดเรียงตาม Callstack: มีประโยชน์เมื่อคุณต้องการค้นหาตำแหน่งที่มี Hotpath ซึ่งมีการจัดสรรหน่วยความจำ เช่น ภายในลูปหรือภายในฟังก์ชันที่เฉพาะเจาะจงซึ่งทำงานด้านการจัดสรรเป็นจำนวนมาก

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

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

      alt_text รูปที่ 10 การทิ้งหน่วยความจำทั้งหมด

      คอลัมน์ขนาดที่คงไว้
      รูปที่ 11 คอลัมน์ขนาดที่คงไว้
  3. วัดผลกระทบของการเพิ่มประสิทธิภาพ

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

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

    ผลกระทบขั้นสุดท้ายของการปรับปรุงหน่วยความจำมีดังนี้

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