วิศวกรซอฟต์แวร์
ในปีนี้ Android ได้เปลี่ยนมาใช้ Compose เป็นหลักอย่างเป็นทางการสำหรับการสร้าง UI ทั้งหมด โดยเปลี่ยนมุมมองเดิมเป็นโหมดการบำรุงรักษา สำหรับ Google Play เส้นทางดังกล่าวเริ่มต้นขึ้นในปี 2020 ตลอดระยะเวลาเกือบ 2 ทศวรรษที่ผ่านมาและมีผู้ใช้หลายพันล้านคน การย้ายข้อมูลไปยัง Jetpack Compose ประสบความสำเร็จได้ด้วยแนวทางปฏิบัติแนะนำที่ได้รับการพิสูจน์แล้ว การทำงานร่วมกันอย่างใกล้ชิดกับทีม Compose หลัก และการพัฒนาเครื่องมืออย่างต่อเนื่อง
ดูว่าการปรับปรุง Google Play ให้ทันสมัยด้วย Compose ช่วยปรับปรุงความเร็วและความเสถียรในระยะยาวได้อย่างไร เซสชันนี้จะอธิบายการเชื่อมต่อเวิร์กโฟลว์การออกแบบ Figma ที่ใช้ Agent กับการใช้งาน Compose, การปรับปรุงคุณภาพโดยอัตโนมัติเพื่อป้องกันการจัดองค์ประกอบใหม่ที่ไม่จำเป็น และการสร้างอินเทอร์เฟซที่สื่อความหมายด้วยสีแบบไดนามิก ตัวพิมพ์ที่หลากหลาย และรูปร่างแบบเลเยอร์ คุณจะได้เรียนรู้กลยุทธ์ที่ผ่านการทดสอบแล้วเพื่อคัดแยกข้อบกพร่องได้เร็วขึ้น และปรับขนาดการย้ายข้อมูล Compose ของคุณเองได้อย่างมั่นใจ
ComposeView โดยตรงที่รูทของกิจกรรมMaterialTheme และไลบรารียูทิลิตีสีของ Material ซึ่งจะช่วยหลีกเลี่ยงการแยกส่วนกิจกรรม แม้ว่าการสร้างรูปแบบสีในเวลาบิลด์จะช่วยจำกัดเวลาในการตอบสนองของรันไทม์ก็ตามBoxWithConstraintsข้อความถอดเสียง
ขอต้อนรับทุกคน
ฉันชื่อ 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 วงจรชีวิตของกิจกรรม คุณจะได้รับผลกระทบแบบใช้แล้วทิ้ง คุณจะได้รับผลข้างเคียง และขึ้นอยู่กับตำแหน่งที่คุณวางไว้ มันจะทำงานในลักษณะที่สอดคล้องกันมาก
ซึ่งเป็นประโยชน์อย่างมากสำหรับเรา
ดังนั้น การเปลี่ยนแปลงทางสถาปัตยกรรมทั้ง 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 จะออกไปข้างนอกเพื่อตอบคำถามที่คุณอาจมี
ขอขอบคุณอีกครั้งที่สละเวลา
@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)
}
}
}