Apps foundation

การย้ายข้อมูลแอป Google Play ที่มีอายุ 2 ทศวรรษไปยัง Jetpack Compose

ลำโพง

  • Kirill Grouchnikov

    วิศวกรซอฟต์แวร์

  • Jon Boekenoogen

    วิศวกรซอฟต์แวร์

เกี่ยวกับ

เกี่ยวกับการเสวนา

ในปีนี้ Android ได้เปลี่ยนมาใช้ Compose เป็นหลักอย่างเป็นทางการสำหรับการสร้าง UI ทั้งหมด โดยเปลี่ยนมุมมองเดิมเป็นโหมดการบำรุงรักษา สำหรับ Google Play เส้นทางดังกล่าวเริ่มต้นขึ้นในปี 2020 ตลอดระยะเวลาเกือบ 2 ทศวรรษที่ผ่านมาและมีผู้ใช้หลายพันล้านคน การย้ายข้อมูลไปยัง Jetpack Compose ประสบความสำเร็จได้ด้วยแนวทางปฏิบัติแนะนำที่ได้รับการพิสูจน์แล้ว การทำงานร่วมกันอย่างใกล้ชิดกับทีม Compose หลัก และการพัฒนาเครื่องมืออย่างต่อเนื่อง

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

สรุป

  • Google Play ย้ายการแสดงผลของผู้ใช้ 97% ไปยังหน้าจอที่ใช้ Compose เท่านั้นเป็นเวลากว่า 6 ปี หน้าเว็บหลักๆ ยังมีอัตราการกระตุกดีขึ้น 30% ในช่วง 14 เดือนที่ผ่านมา
  • การนำไปใช้ทีละส่วนจะช่วยลดความเสี่ยงทางธุรกิจในฐานของโค้ดขนาดใหญ่ ทีมสามารถสร้างความคุ้นเคยในหน้าจอที่มีการเข้าชมต่ำก่อน จากนั้นจึงค่อยโฮสต์ ComposeView โดยตรงที่รูทของกิจกรรม
  • การปรับธีมแบบไดนามิกจะทำงานในโค้ดทั้งหมดโดยใช้การวางซ้อน MaterialTheme และไลบรารียูทิลิตีสีของ Material ซึ่งจะช่วยหลีกเลี่ยงการแยกส่วนกิจกรรม แม้ว่าการสร้างรูปแบบสีในเวลาบิลด์จะช่วยจำกัดเวลาในการตอบสนองของรันไทม์ก็ตาม
  • โฟลว์ข้อมูลแบบทิศทางเดียวและ UI แบบประกาศช่วยลดความซับซ้อนของสถาปัตยกรรมและนำภาวะแข่งขันหลายประเภทออก การเรียกใช้แหล่งข้อมูลและการเปลี่ยนรูปแบบ UI ควบคู่กันช่วยปรับปรุงเวลาในการตอบสนองของการโหลดของ Google Play ได้หลายสิบมิลลิวินาที
  • การตรวจสอบ Lint อัตโนมัติจะบังคับใช้กฎคุณภาพของโค้ดและระบบการออกแบบ Play จะใช้กฎเหล่านี้เพื่อบล็อกสีที่ฮาร์ดโค้ดและแจ้งข้อผิดพลาดที่อาจเกิดขึ้นกับประสิทธิภาพ เช่น BoxWithConstraints

Gemini Notebook

หัวข้อ

  • jetpack-compose
  • การย้ายข้อมูล
  • ประสิทธิภาพ
  • การกำหนดธีม
  • unidirectional-data-flow
  • lint-rules
  • developer-velocity

ข้อความถอดเสียง

ข้อมูลเบื้องต้นและการนำ Google Play Store มาใช้

  • ขอต้อนรับทุกคน

  • ฉันชื่อ Jon

  • เราติดต่อคุณในนามของทีม Google Play Store

  • นี่คือ Kirill เพื่อนร่วมงานของฉัน

  • วันนี้เราจะมาพูดถึงวิธีย้ายโค้ดจำนวนมากจากระบบ View และ Fragment ไปยัง Compose

  • มาเริ่มกันเลยดีกว่า

  • แล้วการนำไปใช้เป็นอย่างไรบ้าง และมีขนาดเท่าใด

  • ฐานของโค้ดแอปของเราเติบโตขึ้นอย่างเป็นธรรมชาติมาตั้งแต่ปี 2007

  • เรามีโค้ดเวอร์ชันที่ใช้งานจริงหลายล้านบรรทัด มีหน้าจอ 200 หน้าจอ และคอมโพเนนต์ UI ที่ไม่ซ้ำกัน 500 รายการซึ่งใช้ในหน้าจอต่างๆ มากมาย

  • ในปี 2020 เราพบว่าความเร็ว ความน่าเชื่อถือ และประสิทธิภาพของนักพัฒนาซอฟต์แวร์เริ่มไม่เป็นไปตามเป้าหมายที่เราต้องการ

  • เราจึงตัดสินใจใช้ชุดซอฟต์แวร์โครงสร้างพื้นฐาน UI ที่ทันสมัย

  • เราได้ประเมินไลบรารีต่างๆ มากมาย

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

  • สบายดีไหม

  • 6 ปีต่อมา ตอนนี้เรามีการแสดงผลต่อผู้ใช้ 97% ภายในแอป Play Store บนหน้าจอที่ใช้ Compose เท่านั้น

  • ขออภัย การพัฒนาโทรศัพท์และหน้าจอขนาดใหญ่ทั้งหมดได้เปลี่ยนไปใช้ Compose เท่านั้นตั้งแต่ปี 2020

  • และแม้แต่อุปกรณ์รูปแบบอื่นๆ ของเรา เช่น XR, TV, Auto, Wear ก็เปลี่ยนมาใช้ Compose ตั้งแต่ปี 2025

  • และ Compose ก็เป็นตัวช่วยสำคัญที่ทำให้เราประสบความสำเร็จ และเป็นเหตุผลที่เรานำมาใช้มากขึ้นเรื่อยๆ

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

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

  • เมื่อพูดถึงประสิทธิภาพโดยเฉพาะ Compose ช่วยให้แอปของเราทำงานได้อย่างราบรื่นและต่อเนื่องในหน้าจอหลักทั้งหมด

  • ซึ่งได้แก่ หน้าผลการค้นหา หน้าแรก และหน้ารายละเอียด

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

  • เราจึงเห็นว่าประสิทธิภาพดีขึ้น 30% ในช่วง 14 เดือนที่ผ่านมา

แผนการย้ายข้อมูล

  • แต่เรามาถึงจุดนี้ได้อย่างไร

  • ซึ่งเป็นสิ่งที่เราจะมาพูดถึงกันในวันนี้

  • เรามาพูดถึงแผนการย้ายข้อมูลกัน

  • ดังนั้น Play จึงใช้แนวทางแบบหลายขั้นตอน

  • เราไม่อยากทุ่มสุดตัวและเสี่ยงกับวิธีเดียว

  • เราได้ดำเนินการ 2-3 ขั้นตอนเพื่อทำความเข้าใจความเสี่ยง ผลกระทบต่อธุรกิจ และสร้างความมั่นใจอย่างแท้จริงก่อนที่จะทุ่มสุดตัว

  • ซึ่งเราจะเรียกขั้นตอนเหล่านี้ว่าการคลาน การเดิน การวิ่งเหยาะๆ และการวิ่ง

  • ดังนั้นการคลานสำหรับเราจึงเป็นการสร้างความคุ้นเคยกับ Compose

  • เราเริ่มต้นด้วยหน้าเว็บที่มีการเข้าชมต่ำ

  • ซึ่งอาจเป็นหน้าการตั้งค่า ใบอนุญาตของบุคคลที่สาม หรืออะไรทำนองนั้น

  • เป้าหมายหลักของคุณคือการสร้างความคุ้นเคยกับไลบรารี Compose

  • ซึ่งอาจเป็นการทำความคุ้นเคยกับแถว คอลัมน์ ข้อความ รูปภาพ และสิ่งต่างๆ เหล่านี้

  • จากนั้นคุณต้องเริ่มนำโครงสร้างพื้นฐานทั้งหมดของแอปมาใช้และทำความเข้าใจวิธีการทำงานในแบบของ Compose

  • ซึ่งอาจเป็นการบันทึกการแสดงผล การบันทึกการคลิก การกำหนดธีม และเรากำลังปรับปรุงการโหลดข้อมูลไปพร้อมๆ กัน

  • ก็คือทุกอย่างที่กล่าวมา

  • และสิ่งหนึ่งที่เราพบว่ามีประโยชน์คือการตรวจสอบว่าหน้าจอทั้งหมดของเราดูสอดคล้องกัน เราได้สร้าง Unit Test และการทดสอบฟังก์ชันเพื่อตรวจสอบว่าออบเจ็กต์การกำหนดธีมใน Compose แมปกับสไตล์ XML, ตัวพิมพ์, สี และสิ่งต่างๆ เหล่านี้โดยตรง

  • เมื่อเราเริ่มคุ้นเคยและรู้สึกสบายใจแล้ว เราจึงตัดสินใจเปลี่ยนไปเดิน

  • สำหรับเราแล้ว การดำเนินการนี้เป็นการนำองค์ประกอบเล็กๆ ในหน้าจอที่มีการเข้าชมสูงมากมาประเมินว่าการย้ายข้อมูลประเภทนั้นเป็นอย่างไร

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

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

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

  • คุณมีสแต็กการแสดงผลที่อยู่ใน Compose ทั้งหมดและสแต็กที่อยู่ใน Views

  • ดังนั้นจึงอาจมีการใช้หน่วยความจำมากเกินไป การโหลดคลาสเพิ่มเติม และอื่นๆ

  • แต่เมื่อคุณใช้ Compose มากขึ้นเรื่อยๆ ปัญหานั้นก็จะหมดไป

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

  • หลังจากเดินแล้ว เราจะเปลี่ยนไปวิ่งจ็อกกิ้ง

  • ดังนั้นนี่คือสิ่งที่เราจะทำเมื่อเราเริ่มคุ้นเคยกับกล้องมากๆ แล้ว

  • แทนที่จะทำองค์ประกอบเดียวในหน้าเว็บที่มีการเข้าชมสูง ให้ทำทั้งหน้าเว็บที่มีการเข้าชมสูง

  • สิ่งที่เราทำในส่วนนี้คือเรายังคงเก็บไลบรารีการนำทางและใช้ Fragment ไว้ แต่สำหรับแต่ละหน้าจอ เราได้นำไปใช้ใน Compose อย่างเต็มรูปแบบ

  • เราเพิ่งให้ Fragment แสดงผล ComposeView เอง

  • ดังนั้นสิ่งที่คุณคาดหวังได้คือเวลาในการตอบสนองและอาการกระตุกที่ลดลง

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

  • และ Compose เองก็ทำการแคชบางระดับที่ระดับ ComposeView ด้วย

  • ดังนั้น หากคุณมี RecyclerView ที่มีการ์ดจำนวนมากซึ่งดูสอดคล้องกันและอาจมีไอคอนเดียวกัน การแยกวิเคราะห์ไอคอนและการใช้ทรัพยากรทั้งหมดจะแชร์กันในทุกอย่างใน ComposeView

  • หลังจากนั้น เราจึงเปลี่ยนไปวิ่ง

  • นี่จึงเป็นช่วงเวลาที่คุณต้องทุ่มสุดตัว

  • เมื่อการเข้าชมส่วนใหญ่มาจากแอปใน Compose เราจะเลื่อนขึ้น 1 ระดับ

  • ดังนั้นเราจึงมีกิจกรรมอยู่เหนือหน้าจอ

  • ดังนั้นให้ย้าย ComposeView ไปยังรูทของกิจกรรม

  • และโค้ดจำนวนมากจะมีลักษณะค่อนข้างคล้ายกัน

  • คุณยังคงพยายามทำตามวิธีการนำทางที่ต้องการพูด เช่น ย้ายจากหน้าจอหนึ่งไปยังอีกหน้าจอหนึ่ง

  • แต่แทนที่จะทำธุรกรรม Fragment คุณจะเรียกใช้ฟังก์ชันที่ประกอบกันได้

  • และคุณสามารถทำเช่นนี้ได้ทั้งในไลบรารี Nav2 หรือ Nav3 แล้วแต่คุณจะเลือก

  • สำหรับเรา เราไม่ได้ย้ายข้อมูลหน้าจอทั้งหมด

  • เราบอกแล้วว่าเรามีเยอะมาก

  • เราจึงสร้างความเข้ากันได้ของ Fragment ซึ่งคุณสามารถมีหน้าจอที่อิงตาม Fragment และใช้ประโยชน์จาก Wrapper AndroidFragment ของ Compose เพื่อดำเนินการนี้ได้

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

  • แต่คุณจะได้รับความสามารถใหม่ๆ ด้วย

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

  • เราจึงมีรูปภาพที่ขยายใหญ่ขึ้นเมื่อคุณเปลี่ยนจากหน้าจอหนึ่งไปยังอีกหน้าจอหนึ่ง ซึ่งช่วยให้เกิดความต่อเนื่อง

  • นอกจากนี้ คุณยังใช้ประโยชน์จากความยืดหยุ่นของภาพเคลื่อนไหวทั้งหมดของ Compose ได้ขณะทำการเปลี่ยนผ่านทั้งหมดนั้น

  • และตอนนี้ฉันจะส่งต่อให้ Kirill พูดถึงความสามารถเพิ่มเติมบางอย่าง

ธีมและประสิทธิภาพ

  • ขอบคุณ Jon

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

  • ในโลกของ View มีโค้ด Java และโค้ด Kotlin ตามมาในภายหลัง จากนั้นก็มีทรัพยากร XML เช่น สี, สตริง, มิติข้อมูล, เลย์เอาต์, ธีม และสไตล์

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

  • มี API Resources.Theme.applyStyle ที่คุณสามารถใช้แบบไดนามิกที่รันไทม์เพื่อใช้การจัดรูปแบบที่กำหนดเองที่ด้านบนของลำดับชั้น UI

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

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

  • การสร้างโมเดลทางความคิดที่เหมาะสมของลำดับชั้นสไตล์ในโลก XML นั้นค่อนข้างยาก

  • และสุดท้าย ไม่มีมุมมองแบบรวมศูนย์เดียวใน Android Studio หรือเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์อื่นๆ ที่ช่วยให้คุณเชื่อมช่องว่างระหว่างโลกของ Java, โลกของโค้ด และโลกของ XML ได้

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

  • ในโลกใหม่ ในโลกของ Compose โดยเฉพาะสำหรับระบบ Material Design และไลบรารี Compose Material รวมถึงระบบการออกแบบอื่นๆ สิ่งที่เรามีสำหรับระบบ Material Design คือเรามี Composable MaterialTheme ที่คุณใช้กับส่วนบนสุดของลำดับชั้น UI บนหน้าจอ และคุณยังใช้ MaterialTheme นี้เป็นโอเวอร์เลย์ในส่วนเล็กๆ ของ UI ได้ด้วย

  • หากดูที่หน้าจอทางด้านขวา คุณจะเห็น Play Points ระดับโกลด์ที่ด้านบน ซึ่งเป็นการ์ดขนาดเล็กที่มีตัวบ่งชี้ความคืบหน้าและข้อความ 2-3 รายการ

  • เราใช้การวางซ้อนธีม Material นี้กับรูปแบบสีที่กำหนดเองซึ่งสร้างโดยไลบรารี Material Color Utilities ซึ่งพร้อมให้คุณใช้งานใน GitHub

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

  • ซึ่งจะช่วยให้นักพัฒนาแอป Android สามารถใช้ความสามารถในการปรับธีมแบบไดนามิกได้อย่างเต็มที่

  • ทุกอย่างทำในโค้ด ทุกอย่างทำใน Kotlin ซึ่งหมายความว่าการสร้างโมเดลทางความคิดที่เหมาะสมเกี่ยวกับวิธีการทำงานทั้งหมดจะง่ายขึ้นมาก และการแก้ไขข้อบกพร่องก็จะง่ายขึ้นมากด้วย

  • และภายใน ระบบจะแนบการวางซ้อนนี้เป็น Composition Local กับโหนด UI ที่เฉพาะเจาะจงในลำดับชั้นที่คุณเลือกใช้

  • ข้อควรพิจารณาด้านประสิทธิภาพ: การสร้างรูปแบบสีแบบเต็มด้วยไลบรารี Material Color Utilities มีค่าใช้จ่าย

  • ซึ่งอาจมีค่าใช้จ่ายเพิ่มเติมบางอย่าง

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

  • ดังนั้น ข้อแรก คุณควรเริ่มวัดผลกระทบที่มีต่อประสิทธิภาพ และข้อ 2 คุณสามารถลดภาระงานบางส่วนจากรันไทม์ไปเป็นเวลาบิลด์ได้

  • คุณสามารถใช้ไลบรารี Material Color Utilities เดียวกันนี้ในเวลาบิลด์เพื่อสร้างรูปแบบสีเหล่านั้นล่วงหน้าตามความต้องการด้านการสร้างแบรนด์หรือตามความต้องการของผลิตภัณฑ์ และลดภาระงานนี้ในเวลาบิลด์

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

  • ดังนั้นเมื่อใช้หลายๆ ตัวเข้า ไม่ว่าจะหลายสิบหรือหลายร้อยตัว ก็จะเริ่มมีค่าใช้จ่ายเพิ่มขึ้นเรื่อยๆ

  • และเมื่อถึงจุดหนึ่ง คุณจะต้องเริ่มพิจารณาต้นทุนของ CompositionLocal ทั้งหมดที่รวมกันนี้

  • และนี่คือตัวอย่างของสิ่งที่ฉันพูดถึง ซึ่งคล้ายกับความสามารถในการกำหนดธีมรันไทม์แบบไดนามิกที่แท้จริงของ Compose

  • เรามี 4 จตุภาค ภาพเดียวกัน และเราจะเรียกสิ่งนี้ว่าการ์ดกิจกรรม

  • เรามีรูปภาพหลักที่ครอบคลุมทั้งการ์ด จากนั้นเรามีป้ายกำกับที่ด้านซ้ายบน ปุ่มที่ด้านขวาล่าง และข้อความ 2-3 รายการ

  • และทางด้านขวาของแต่ละจตุภาค คุณจะเห็นข้อความไฮไลต์ของโทเค็นสีที่ใช้เป็นข้อกำหนดการออกแบบสำหรับแต่ละองค์ประกอบ

  • การติดตั้งใช้งานการ์ดจะเหมือนกันทั้งหมดสำหรับทั้ง 4 รายการนี้

  • ความแตกต่างเพียงอย่างเดียวคือการวางซ้อนการกำหนดธีม Material ที่รวมการ์ดไว้จะสร้างขึ้นหรือกำหนดค่าด้วยรูปแบบสีที่สร้างขึ้นแบบไดนามิกตามสีที่โดดเด่นของรูปภาพ ได้แก่ สีน้ำเงิน สีม่วง สีเหลือง และสีแดง

  • ส่วนอื่นๆ ทั้งหมดจะยังคงเหมือนเดิม

  • คุณไม่จำเป็นต้องลบและสร้างกิจกรรมใหม่

  • คุณสามารถใช้แบบมีเงื่อนไขตามแฟล็กการทดสอบหรือความต้องการทางธุรกิจอื่นๆ ได้

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

  • ตอนนี้เราจะส่งต่อให้ Jon พูดถึงส่วนถัดไป

การปรับขนาดความน่าเชื่อถือและความเร็ว

  • ใช่

  • นี่คือความยืดหยุ่นเพิ่มเติมที่ Kirill พูดถึง

  • เรามาพูดถึงความเสถียรและความเร็วกัน

  • ดังนั้น การสร้างโค้ดคุณภาพสูงอย่างรวดเร็วจึงเป็นสิ่งที่นักพัฒนาซอฟต์แวร์และธุรกิจทั้งหมดมองหา

  • มาดูกันว่า Compose ช่วยให้ Google Play ทำเช่นนั้นได้อย่างไร

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

  • เราจะไม่ลงลึกในเรื่องนี้มากนัก แต่หนึ่งในโมเดลทางความคิดที่ Compose พยายามนำเสนอคือเรื่องการไหลของข้อมูลแบบทิศทางเดียว ซึ่งส่งผลต่อทีมของเราอย่างมาก

  • สำหรับผู้ที่ไม่คุ้นเคยกับวิธีการทำงานของฟีเจอร์นี้ หลักการพื้นฐานคือคุณมีแหล่งข้อมูล

  • แหล่งข้อมูลจะให้ข้อมูล

  • ข้อมูลดังกล่าวอาจเปลี่ยนรูปแบบเป็น UI ที่เฉพาะเจาะจง ซึ่งเราจะแสดงผลเป็นโมเดล UI

  • จากนั้น Compose จะสังเกตเห็นได้อย่างง่ายดายเพียงแค่เรียกใช้พร็อพเพอร์ตี้ค่าในสถานะนั้น

  • ซึ่งก็คือลูกศรที่อยู่ด้านบนของแผนภาพนี้

  • จากนั้นเหตุการณ์จะไหลไปในทิศทางตรงกันข้าม

  • ดังนั้น หากผู้ใช้คลิกปุ่ม ระบบจะกลับไปที่ UI Transformer, อัปเดตแหล่งข้อมูลที่ปล่อยค่าใหม่, เรียกใช้การเปลี่ยนรูปแบบ และคุณจะได้รับลูปนี้

  • ดังนั้นทุกอย่างจึงทำงานผ่านลูปที่ค่อนข้างเรียบง่ายนี้

  • ประโยชน์ที่เราเห็นได้ชัดจากวิธีนี้คือช่วยลดช่วงเวลารวบรวมข้อมูลเริ่มต้น

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

  • โดยจะวนซ้ำตามลูปทั่วไป 1 ลูป

  • Compose ช่วยให้การสังเกตข้อมูลเป็นไปอย่างตรงไปตรงมา และข้อมูลมีการรับประกันความสอดคล้องที่อัปเดตทันทีในเลเยอร์สถาปัตยกรรมต่างๆ

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

  • ประโยชน์ที่สำคัญอีกอย่างหนึ่งสำหรับเราคือเมื่อเทียบกับสถาปัตยกรรม Model-View-Controller ที่เราเคยใช้ก่อนหน้านี้ การดำเนินการแหล่งข้อมูลและการเปลี่ยนรูปแบบ UI แบบขนานกลายเป็นเรื่องที่ตรงไปตรงมาอย่างมาก

  • ซึ่งช่วยปรับปรุงเวลาในการตอบสนองของการโหลดภายใน Store ได้หลายสิบมิลลิวินาทีหรือประมาณนั้น

  • ซึ่งเป็นเรื่องที่น่าประทับใจมากสำหรับเรา

  • เมื่อจับคู่กับโฟลว์ข้อมูลแบบทิศทางเดียว ผู้สนับสนุนรายใหญ่อีกรายของ Compose ก็คือ UI แบบประกาศ

  • Kirill ได้พูดถึงเรื่องนี้ไปบ้างแล้ว

  • นักพัฒนาแอป Google Play จึงชื่นชอบฟีเจอร์นี้มากเช่นกัน

  • ตอนนี้ขั้นตอนการควบคุม UI อยู่ในไฟล์เดียวแล้ว

  • เรามีตัวอย่างทางด้านขวาซึ่งค่อนข้างตรงไปตรงมา

    @Composable
    fun PurchaseRow(onClick: () -> Unit, modifier: Modifier) {
      Row(modifier) {
        Text("20% off sale")
        if (LocalExpts.current.useButtonV2) {
          ButtonV2("Buy", onClick = onClick)
        } else {
          ButtonV1("Buy", onClick = onClick)
        }
      }
    }
  • เรากำลังเปลี่ยนการใช้งานปุ่ม 2 แบบตามแฟล็กการทดสอบ

  • แทนที่จะต้องอ่านไฟล์มุมมองหลายไฟล์ หรือไฟล์ Fragment และไฟล์ XML คุณก็แค่อ่านจากบนลงล่าง ซึ่งทำให้ง่ายขึ้นมาก

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

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

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

  • ซึ่งเป็นประโยชน์อย่างมากสำหรับเรา

การเตรียมความพร้อมสำหรับ LLM

  • ดังนั้น การเปลี่ยนแปลงทางสถาปัตยกรรมทั้ง 2 อย่างนี้จึงเป็นรากฐานสำคัญสำหรับ LLM ในมุมมองของฉัน และช่วยให้ LLM สร้างโค้ดที่มีคุณภาพสูงได้

  • และเราเชื่อว่าหลายคนคงเคยลองหรือทำแบบนี้กับ LLM ที่คุณชื่นชอบ

  • คุณอาจถ่ายภาพหน้าจอที่มีคำอธิบายประกอบด้วยสีและการจัดพิมพ์ แล้วป้อนเข้าไป และดูว่าสามารถสร้างแถว คอลัมน์ ข้อความ และปุ่มได้ และทำได้ดีพอสมควร

  • แต่ก็มีข้อจำกัดอยู่บ้าง

  • และสิ่งที่ Play เห็นจริงๆ คือไม่เข้าใจฐานของโค้ดของคุณใช่ไหม

  • AI ไม่รู้ว่าคุณสร้างคอมโพเนนต์ใดไว้แล้วบ้างที่ควรนำมาใช้ซ้ำ และไม่รู้ชื่อโทเค็นการออกแบบ

  • แต่จะให้สีและสตริงที่ฮาร์ดโค้ดเท่านั้น

  • เนื้อหาใดควรมาจากอุปกรณ์ เนื้อหาใดควรมาจากเซิร์ฟเวอร์ หรือฉันจะแน่ใจได้อย่างไรว่าเนื้อหานั้นมีประสิทธิภาพในการใช้ LazyList และไม่ได้เป็นเพียงคอลัมน์ขนาดใหญ่

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

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

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

  • ดังนั้น คุณจะได้ผลลัพธ์ที่คล้ายกับสิ่งที่เรามีก่อนหน้านี้ โดยเปลี่ยนไปเป็นหลังจากนั้น

  • ฉันไม่ได้ใส่กรอบล้อมรอบไว้ที่นี่เพราะจะทำให้แผนภาพดูรกเกินไป

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

  • เราได้ทำเครื่องหมายชื่อคอมโพเนนต์ไว้อย่างชัดเจน เช่น ส่วนหัวของการ์ดและป้ายไอคอน

  • ซึ่งจะทำให้พบข้อมูลเหล่านั้นในฐานของโค้ด

  • และสำหรับเรา เรามีสิ่งเหล่านี้จำนวนมากที่มาจากไลบรารีการออกแบบทั่วไปด้วย ซึ่ง Kirill จะพูดถึงในอีกสักครู่

  • คุณจึงไม่ต้องติดป้ายกำกับที่กำหนดเองให้กับผลิตภัณฑ์ทั้งหมดตลอดเวลา

  • คุณจับคู่สิ่งนั้นกับซิกเนเจอร์ของเมธอดเหมือนที่เรามีที่ด้านล่าง OfferCard จากนั้นระบบจะทราบว่าชื่อ endDate และรูปภาพเป็นแบบไดนามิกทั้งหมด

  • เราไม่ควรฮาร์ดโค้ดสิ่งเหล่านั้น

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

  • และด้วยเหตุนี้ เราจึงสร้างโค้ดได้มากขึ้น

  • ผมจะส่งต่อให้ Kirill พูดถึงวิธีที่เรารักษาคุณภาพ

การทำงานอัตโนมัติที่มีคุณภาพ

  • ขวา

  • ขอบคุณ Jon

  • ดังนั้น เพื่อสานต่อหัวข้อ LLM และการพัฒนาที่ใช้ Agent Assist ช่วยนี้ เราจะเริ่มจากด้านการออกแบบ UX ก่อน

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

  • บางทีอาจเป็น Material

  • บางทีอาจเป็นระบบการออกแบบที่กำหนดเองของคุณ

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

  • เพื่อให้นักออกแบบสามารถสลับระหว่างชุดค่าผสมต่างๆ เหล่านี้ได้อย่างรวดเร็วเพื่อดูว่าข้อกำหนดการออกแบบตอบสนองต่อชุดค่าผสมนั้นอย่างไร

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

  • และสุดท้าย สิ่งที่เราพบว่ามีประโยชน์มากในระดับ Google Play คือเรามีคอมโพเนนต์ คลัสเตอร์ การ์ด คอนเทนเนอร์หลายร้อยรายการที่ใช้ในหน้าจอต่างๆ ที่เรามี

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

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

  • ซึ่งช่วยลดต้นทุนด้านการออกแบบและต้นทุนการติดตั้งใช้งานได้อย่างมาก

  • ในด้านการใช้งาน เราพึ่งพากฎ Lint หลักและกฎ Lint ที่กำหนดเองเป็นอย่างมาก

  • กฎ Lint หลัก 2 ข้อที่ฉันอยากพูดถึงคือ FrequentlyChangingValueDetector ซึ่งช่วยระบุแหล่งที่มาของการจัดองค์ประกอบใหม่ที่ไม่จำเป็น ซึ่งอาจทำให้เกิดเวลาในการตอบสนองและอาการกระตุก และอีกกฎหนึ่งคือ ScaffoldPaddingDetector สำหรับแจ้งกรณีที่เราใช้คอมโพสิเบิล Scaffold ของ Material Compose แต่ละเลยระยะห่างจากขอบที่เข้ามา

  • ซึ่งไม่ใช่สาเหตุของเวลาในการตอบสนองและอาการกระตุก แต่ในบางกรณีอาจทำให้แก้ไขข้อบกพร่องได้ยากมาก เช่น การจัดวางเลย์เอาต์ไม่ถูกต้องในบางกรณี เช่น แบบไร้ขอบ หรือการพับและกางออก

  • และสุดท้าย BoxWithConstraints มาพร้อมกับข้อควรพิจารณาด้านประสิทธิภาพบางประการ

  • อาจต้องใช้ 2 เฟรมเพื่อจัดวางทุกอย่างให้เหมาะสม

  • เราไม่ได้บล็อกโดยสิ้นเชิง แต่เราจะแจ้งว่าเป็นการเตือน Lint เพื่อให้นักพัฒนาแอปที่ทำงานบนหน้าจอนั้นทราบว่าตนกำลังเลือกใช้ BoxWithConstraints หรืออาจเลือกใช้สิ่งอื่นสำหรับเลย์เอาต์นั้นๆ

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

  • เรามีกฎ Lint ที่บล็อกการใช้สีและตัวอักษรที่ฮาร์ดโค้ด

  • เรามีกฎ Lint ที่แจ้งว่ามีการใช้คอมโพเนนต์ Material 2

  • เราต้องการใช้เฉพาะ Material 3 ซึ่งเป็นเวอร์ชันล่าสุดและดีที่สุด รวมถึงคอมโพเนนต์ใหม่ที่สื่อความหมายได้ดีขึ้นซึ่งเปิดตัวเมื่อปีที่แล้วและปีนี้

  • เรามีกฎ Lint ที่กำหนดเองซึ่งป้องกันไม่ให้ผู้ใช้อ่านสีจากไฟล์ XML เดิม

  • เราต้องการใช้ Compose เป็นหลักและใช้ Compose เท่านั้นสำหรับหน้าจอใหม่

  • และ Text Composable โดยเฉพาะในระบบการออกแบบ Material จะมีรูปแบบและสีสำรอง

  • โดยจะอ่านจากสีของเนื้อหาในเครื่องและแบบตัวพิมพ์ในเครื่อง แต่เราไม่ต้องการพึ่งพาสิ่งนั้น

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

  • นั่นคือกฎ Lint ที่เรามี

  • และสุดท้าย เช่นเดียวกับ ScaffoldPaddingDetector เรามีกฎ Lint ที่กำหนดเองซึ่งบังคับใช้ว่าฟังก์ชันที่ประกอบกันได้ทุกฟังก์ชันที่เรามีจะใช้ตัวแก้ไขอินพุต

  • ขอย้ำอีกครั้งว่าเพื่อป้องกันไม่ให้การใช้งานใหม่ๆ วางผิดตำแหน่ง หรือไม่เคารพพื้นหลังที่เข้ามา หรืออะไรก็ตามที่อาจเกิดขึ้น

บทสรุป

  • และนี่คือ 3 ประเด็นหลักที่เราอยากให้คุณได้รับจากการนำเสนอนี้

  • ข้อแรกคือในปัจจุบัน ณ สิ้นปี 2026 เรามองว่า Compose เป็น UI Toolkit ที่สมบูรณ์และได้รับการพิสูจน์แล้วว่าใช้งานได้ในวงกว้าง

  • Android เองก็ใช้ Compose เป็นหลัก

  • เมื่อต้นปีนี้ที่งาน Google I/O เราได้ประกาศว่าไลบรารี UI และโฟลว์ Agent ทั้งหมดจะใช้ Compose เป็นหลัก

  • และอย่างที่ Jon ได้กล่าวไว้ก่อนหน้านี้ในงานนำเสนอว่า ค่อยๆ เริ่มต้นจากก้าวเล็กๆ ไปสู่ก้าวที่ใหญ่ขึ้น เราขอแนะนำให้คุณย้ายข้อมูลทีละส่วน โดยเฉพาะฐานของโค้ดขนาดใหญ่ เพื่อเร่งความเร็วของโฟลว์นักพัฒนาซอฟต์แวร์และโฟลว์ Agent

  • เราขอขอบคุณที่สละเวลามาเข้าร่วมเซสชันในวันนี้ และในอีกไม่กี่นาทีข้างหน้า เราและ Jon จะออกไปข้างนอกเพื่อตอบคำถามที่คุณอาจมี

  • ขอขอบคุณอีกครั้งที่สละเวลา

รหัส

ข้อมูลโค้ด

ข้อมูลโค้ด Kotlin ที่เวลา 16:09 ใน "การปรับขนาดความน่าเชื่อถือและความเร็ว"
@Composable
fun PurchaseRow(onClick: () -> Unit, modifier: Modifier) {
  Row(modifier) {
    Text("20% off sale")
    if (LocalExpts.current.useButtonV2) {
      ButtonV2("Buy", onClick = onClick)
    } else {
      ButtonV1("Buy", onClick = onClick)
    }
  }
}