โหมดการข้ามแบบเข้มงวด

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

  • Composable ที่มีพารามิเตอร์ที่ไม่เสถียรจะกลายเป็นข้ามได้
  • แลมบ์ดาที่มีการจับภาพไม่เสถียรจะถูกจดจำ

เปิดใช้โหมดการข้ามแบบเข้มงวด

หากต้องการเปิดใช้การข้ามอย่างเข้มงวดสำหรับโมดูล Gradle ให้ใส่ตัวเลือกต่อไปนี้ใน บล็อก composeCompiler ของการกำหนดค่า Gradle

android { ... }

composeCompiler {
   enableStrongSkippingMode = true
}

ความสามารถในการข้ามที่ประกอบกันได้

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

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

ควรข้ามเมื่อใด

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

  • ระบบจะเปรียบเทียบพารามิเตอร์ที่ไม่เสถียรโดยใช้ความเท่าเทียมกันของอินสแตนซ์ (===)
  • ระบบจะเปรียบเทียบพารามิเตอร์ที่เสถียรโดยใช้ความเท่าเทียมกันของออบเจ็กต์ (Object.equals())

ถ้าพารามิเตอร์ทั้งหมดตรงตามข้อกำหนดเหล่านี้ Compose จะข้าม Composable ระหว่าง การจัดองค์ประกอบใหม่

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

@NonSkippableComposable
@Composable
fun MyNonSkippableComposable {}

ใส่คำอธิบายประกอบคลาสว่าเสถียร

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

การบันทึก Lambda

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

ตัวอย่าง

หากต้องการบันทึกเสียง lambdas ภายใน Composable เมื่อใช้การข้ามอย่างแรง คอมไพเลอร์จะรวม lambda ของคุณด้วยการเรียก remember คีย์นี้มาพร้อมกับ ที่ออกมาตอนแรก

ลองพิจารณากรณีที่คุณมี lambda ตามตัวอย่างต่อไปนี้

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = {
        use(unstableObject)
        use(stableObject)
    }
}

เมื่อเปิดใช้การข้ามแบบเร็ว คอมไพเลอร์จะบันทึก lambda ด้วยการรวมเข้าไว้ การโทรหา remember:

@Composable
fun MyComposable(unstableObject: Unstable, stableObject: Stable) {
    val lambda = remember(unstableObject, stableObject) {
        {
            use(unstableObject)
            use(stableObject)
        }
    }
}

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

การบันทึกและการเรียบเรียงใหม่

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

หลีกเลี่ยงการบันทึก

ถ้าคุณมี lambda ที่ไม่ต้องการบันทึก ให้ใช้ @DontMemoize หมายเหตุ

val lambda = @DontMemoize {
    ...
}

ขนาด APK

เมื่อคอมไพล์แล้ว Composable แบบข้ามได้จะทำให้มีโค้ดที่สร้างขึ้นมากกว่า Composable ที่ข้ามไม่ได้ เมื่อเปิดใช้การข้ามขั้นสูง ทำเครื่องหมาย Composable เกือบทั้งหมดเป็นแบบข้ามได้และรวม lambda ทั้งหมดไว้ในแท็ก remember{...} ด้วยเหตุนี้ การเปิดใช้โหมด การข้ามขั้นสูง ผลกระทบต่อขนาด APK ของแอปพลิเคชัน

การเปิดใช้การข้ามอย่างเข้มงวดใน Now In Android ช่วยเพิ่ม APK ขนาด 4 KB ความแตกต่างของขนาดส่วนใหญ่แล้วจะขึ้นอยู่กับจำนวน Composable ที่ข้ามไม่ได้ซึ่งมีอยู่ในแอปที่กำหนด แต่ควรเป็น ค่อนข้างเล็ก