- Valdi ที่สร้างโดย Snap เป็น เฟรมเวิร์ก UI ข้ามแพลตฟอร์ม ที่มอบ ประสิทธิภาพแบบเนทีฟ บน iOS, Android และ macOS โดยคอมไพล์ UI ที่เขียนด้วย TypeScript แบบประกาศเชิงพรรณนาให้เป็นเนทีฟวิวของแต่ละแพลตฟอร์มโดยตรง
- ทำงานได้ โดยไม่ต้องใช้ WebView หรือ JavaScript bridge และคงประสิทธิภาพสูงด้วย การรีไซเคิลวิวอัตโนมัติ, เอนจินเลย์เอาต์ที่ปรับแต่งมาอย่างเหมาะสม, การเรนเดอร์ตาม viewport เป็นต้น
- เร่งความเร็วในการพัฒนาด้วย hot reload ทันที, การดีบักใน VSCode, รองรับไวยากรณ์ TSX และยังรองรับ การผสานรวมกับแอปเนทีฟเดิม ได้อย่างยืดหยุ่น
- มอบโครงสร้างการผสานรวมเนทีฟเชิงลึกด้วย การ bind แบบ type-safe ระหว่าง TypeScript กับโค้ดเนทีฟ, รองรับ protobuf, การเชื่อมต่อกับ C++·Swift·Kotlin
- เป็น เทคโนโลยีที่ผ่านการพิสูจน์ในแอป production ของ Snap ตลอด 8 ปี และเป็น รากฐานสำหรับการพัฒนา UI ที่ขยายต่อได้ พร้อมฟีเจอร์ขั้นสูงอย่างแอนิเมชันขนาดใหญ่, gesture และการประมวลผลแบบมัลติเธรด
ภาพรวมของ Valdi
- Valdi คือ เฟรมเวิร์ก UI ข้ามแพลตฟอร์ม ที่ Snap ใช้งานในแอป production มานาน 8 ปี
- เมื่อเขียน UI ด้วย TypeScript แบบประกาศเชิงพรรณนา ระบบจะ คอมไพล์เป็นเนทีฟวิวของ iOS, Android และ macOS โดยตรง
- มอบประสิทธิภาพแบบเนทีฟ โดยไม่ต้องใช้ WebView หรือ JavaScript bridge
- ปัจจุบันยังอยู่ใน ช่วงเบตา และมีแผนจะออกเวอร์ชันทางการเมื่อเครื่องมือและเอกสารในสภาพแวดล้อมโอเพนซอร์สมีความเสถียรเรียบร้อยแล้ว
คุณสมบัติหลักและตัวอย่าง
- ตัวอย่างคอมโพเนนต์พื้นฐานใช้คลาส
HelloWorld เพื่อสร้าง UI อย่างง่ายด้วย และ
- ใช้โครงสร้างคอมโพเนนต์แบบประกาศเชิงพรรณนาบนพื้นฐาน TypeScript และสามารถรันโค้ดเดียวกันได้บนแต่ละแพลตฟอร์ม
- มีเอกสารทางการ, คู่มือติดตั้ง, API reference, Codelab และสื่อสำหรับนักพัฒนาให้ใช้งาน
การเพิ่มประสิทธิภาพ
- เพื่อให้ได้ ประสิทธิภาพแบบเนทีฟ จึงเลือกใช้โครงสร้างดังต่อไปนี้
- การรีไซเคิลวิวอัตโนมัติ: ระบบ view pooling แบบ global สำหรับนำวิวกลับมาใช้ซ้ำข้ามหน้าจอ เพื่อลดความล่าช้าจากการ inflate ให้น้อยที่สุด
- การเรนเดอร์คอมโพเนนต์อย่างอิสระ: อัปเดตเฉพาะคอมโพเนนต์แต่ละตัวได้โดยไม่กระทบต่อการเรนเดอร์ของ parent
- เอนจินเลย์เอาต์ที่พัฒนาด้วย C++: ทำงานบน main thread ด้วย overhead ต่ำที่สุด
- การเรนเดอร์แบบรับรู้ viewport: inflate เฉพาะวิวที่มองเห็นบนหน้าจอ เพื่อเพิ่มประสิทธิภาพของ infinite scroll
- มีเอกสารที่เกี่ยวข้องคือ Performance Optimization Guide
ประสบการณ์นักพัฒนา
- ฟีเจอร์ hot reload ช่วยให้การเปลี่ยนโค้ดสะท้อนผลได้ทันที
- รองรับการดีบักใน VSCode: ตั้ง breakpoint, ตรวจสอบตัวแปร, profiling ประสิทธิภาพ และจับ heap dump ได้
- มอบสภาพแวดล้อมการพัฒนาที่คุ้นเคยด้วย ไวยากรณ์ TSX และ type safety
โครงสร้างการผสานรวมที่ยืดหยุ่น
- สามารถ ฝัง Valdi ลงในแอปเนทีฟเดิม ได้ (
Embed Valdi in native)
- สามารถ ใช้เนทีฟวิวภายใน Valdi ได้ (
Embed native in Valdi)
- เชื่อมต่อกับโค้ด C++, Swift, Kotlin และ Objective-C ได้อย่าง type-safe ผ่าน Polyglot module
- ด้วย สถาปัตยกรรม full-stack จึงสามารถใช้ background worker thread เพื่อสร้างฟังก์ชันครบวงจรได้
การผสานรวมกับเนทีฟ
- ใช้ การสร้างโค้ดอัตโนมัติ เพื่อแปลง TypeScript interface ให้เป็น Kotlin, Objective-C และ Swift bindings
- เข้าถึง platform API และไลบรารีเนทีฟของ third-party ได้โดยตรงผ่าน Polyglot module
- รองรับ การสื่อสารสองทาง เพื่อแลกเปลี่ยนโครงสร้างข้อมูลที่ซับซ้อนและ callback ได้อย่างปลอดภัย
- รองรับ protobuf เพื่อให้ทำ data serialization ได้อย่างมีประสิทธิภาพ
ความเสถียรและความสามารถที่ผ่านการพิสูจน์แล้ว
- เป็นเทคโนโลยีหลักที่ขับเคลื่อนฟีเจอร์ production สำคัญของ Snap
- รองรับ แอนิเมชันขั้นสูง, การเรนเดอร์แบบเรียลไทม์, ระบบ gesture ที่ซับซ้อน
- มีฟีเจอร์หลากหลาย เช่น Flexbox layout, multithread worker, native animation, advanced gesture recognition, built-in test framework, Bazel integrated build เป็นต้น
การสนับสนุนและไลเซนส์
- มีการสนับสนุนผ่าน ชุมชน Discord
- เปิดเผยภายใต้ ไลเซนส์ MIT จึงสามารถใช้งานและมีส่วนร่วมได้อย่างอิสระ
2 ความคิดเห็น
ความเห็นจาก Hacker News
บริษัทของเราใช้ React Native อยู่ และอยากให้ความต่างระหว่าง App Store กับภาษาของแต่ละแพลตฟอร์มหายไปเสียที
ปีหน้ากำลังคิดว่าจะใช้แค่เว็บไซต์เป็นหลัก แล้วห่อแอปมือถือด้วย WebView พร้อมทำฟีเจอร์อย่างการแจ้งเตือน, GPS, HealthKit ด้วยโค้ดเนทีฟเท่านั้น
ช่วงนี้ก็เริ่มคิดว่าเพราะมี AI การทำ UI แยกสำหรับแต่ละแพลตฟอร์มอาจจะดีกว่าก็ได้
แกนสำคัญคืออย่าทำคอมโพเนนต์ UI ให้แปลกเกินไป และปรับแค่เรื่องอย่างสไตล์ปุ่มหรือ back stack ให้ต่างกันเล็กน้อยตามแพลตฟอร์ม
อีกอย่าง ผมเพิ่มความสามารถออฟไลน์ด้วย Service Worker และรันเครื่องมือวินิจฉัยเครือข่ายตอนเริ่มแอปเพื่อให้หาปัญหาได้เร็ว
แต่แอปของผมเป็นงาน B2B เลยใช้สถาปัตยกรรมแบบนี้ได้
ผมมองว่าเว็บมีไว้เพื่อเลี่ยง App Store กับการเซ็นโค้ดตั้งแต่แรก
ฟีเจอร์ส่วนใหญ่ทำบนเว็บได้อยู่แล้ว และถ้าเป็น HealthKit ก็แยกเป็น companion app ต่างหากได้
การเอางบการตลาดไปโปรโมต QR code หรือลิงก์อาจคุ้มกว่าการไปแข่งใน App Store มาก
โดยเฉพาะบน iOS พอไม่มี ‘ปัดเพื่อย้อนกลับ’ ก็รู้ได้ทันทีเลยว่านี่คือ WebView
ผมเขียน business UI ครั้งเดียว แล้วใช้ LLM แปลงระหว่าง React Native กับ React
แต่ Apple ก็ยังคงกฎ 4.2 Minimum Functionality ที่ว่า “แอปที่แค่ห่อเว็บไซต์มาเฉย ๆ จะถูกปฏิเสธ” เหมือนเดิม
คุณต้องซิงก์ฟีเจอร์และการทดสอบบนทั้งสามแพลตฟอร์ม และนักพัฒนาก็ต้องเก่งหลายสแตก
ผู้ใช้ส่วนใหญ่แทบไม่รู้สึกถึงความต่างระหว่าง WebView ที่ทำดี ๆ กับแอปเนทีฟ แต่ต้นทุนที่ต้องจ่ายสูงเกินไป
ในเชิงแนวคิด Valdi ดูคล้าย React Native
ตอนนี้มีเฟรมเวิร์กครอสแพลตฟอร์มสาย React อยู่ถึง 3 ตัวคือ React Native, Lynx.js(ByteDance/TikTok), Valdi
การแข่งขันเป็นเรื่องดี แต่ก็สงสัยว่าจะสร้าง ecosystem ให้ใหญ่ได้เร็วเท่า RN หรือไม่
ปีนี้ RN มีพัฒนาการเยอะ ทั้ง การปรับปรุง Hermes engine, native binding generator, multithreaded animation, รองรับ Tailwind เป็นต้น
ส่วน Lynx.js อาจได้เปรียบกว่าในแง่ที่พยายามรองรับเฟรมเวิร์กนอกเหนือจาก React ด้วย
Radon IDE ของ RN เป็นแบบเสียเงิน แต่ Valdi เป็นโอเพนซอร์ส
อีกจุดที่น่าสนใจคือ Valdi ใช้ Hermes engine ของ RN
พอดู เอกสารที่เกี่ยวข้อง ก็ชวนให้สงสัยว่าเขาทำ AOT/JIT กันอย่างไร
เมื่อก่อนผมเคยช่วยดีบักเวอร์ชันแรก ๆ ของโปรเจกต์นี้ที่ Snap (Screenshop!)
Simon เป็นวิศวกรที่ยอดเยี่ยม และดีใจมากที่โปรเจกต์นี้ถูกเปิดออกสู่สาธารณะ
ขอแสดงความยินดีกับทีม Snap
ยิ่งน่าแปลกเพราะเป็นแอปที่การผสานกับเนทีฟสำคัญมาก ทั้งกล้อง, AR, การแจ้งเตือน, การตรวจจับภาพหน้าจอ
ดีใจที่มันกลายเป็นจริง
เขาเป็นคนที่ฉลาดมากจริง ๆ และขอแสดงความยินดีกับทั้งทีม
เป็น เฟรมเวิร์ก UI ที่ Snapchat ทำ แถมมี ชุมชนบน Discord อีก สำหรับผมไม่ดึงดูดเลย
มันไม่สมบูรณ์แบบหรอก แต่ถ้าไม่ไปก็อาจเท่ากับตัดตัวเองออกจากทิศทางของอนาคต
ในเอกสารเขียนว่า “ถ้าเปิดเผยอ็อบเจ็กต์ C++, Objective-C, Kotlin ให้ TypeScript จะเรียกว่า Native Reference ส่วนกลับกันจะเรียกว่า JS Value Reference”
แต่การที่ ไม่มีการพูดถึง Swift หรือ SwiftUI เลย ทำให้กังวลนิดหน่อย
พูดตรง ๆ คือเชื่อใจเฟรมเวิร์กที่ Snap ทำได้ยาก
เพราะเมื่อก่อน คุณภาพแอป Android แย่มาก
Valdi ถูกอธิบายว่าเป็น “เฟรมเวิร์ก UI ที่เขียนครั้งเดียวด้วย TypeScript แล้วรันด้วยประสิทธิภาพระดับเนทีฟบน iOS, Android, macOS”
โดยเน้นว่าไม่มี webview หรือ JS bridge
ผมคิดว่าแค่ เขียน UI ด้วยภาษาเนทีฟของแต่ละแพลตฟอร์ม 2 รอบ แล้วแชร์ logic ร่วมกันผ่าน C-family FFI ก็พอแล้ว
มันจะยากอะไรนักหนา?
คนส่วนใหญ่ในทีมใช้ Android แต่ลูกค้าหลักเป็นฝั่ง iOS เลยจัดลำดับความสำคัญแบบนั้น
ผมเคยมีประสบการณ์ทำแอป RN มาก่อน แต่ก็ยังรอคอย โซลูชันครอสแพลตฟอร์มแบบเวทมนตร์ของจริง อยู่ดี
แบบนั้นไม่ว่าจะเป็นเว็บ, มือถือ, เดสก์ท็อป, CLI ก็จะเป็นแค่เลเยอร์บาง ๆ ที่เรียกใช้แกนกลาง
แม้จะทำ UX ให้สอดคล้องกันเป๊ะ ๆ ได้ยาก แต่ระยะยาวแล้วช่วยลด การพึ่งพาเฟรมเวิร์กจากบุคคลที่สาม ได้
ถ้าอยากรู้ว่า Valdi จัดการ state management อย่างไร มันใช้สไตล์ React class component แบบเดิม
ดูจาก ตัวอย่างในเอกสารทางการ จะเป็นโครงสร้างที่สืบทอด
StatefulComponentแล้ว implementonCreate,onDestroy,onRenderวิธีแบบทุกวันนี้ที่ต้องใช้
useFunctionเป็นสิบ ๆ ตัวทั้งผิดพลาดง่ายและซับซ้อนน่าเสียดายที่ ยังไม่รองรับ Linux, Windows, HTML target
ใน RN ลอจิกธุรกิจของแอปส่วนใหญ่สามารถรันได้เร็วเพียงพอด้วย JS อย่างเดียว
แต่พอขัดเกลาไปเรื่อย ๆ ปัญหาคือ "มักมีกรณีที่การทำงานต่างกันไปตามแต่ละแพลตฟอร์ม" ทำให้ยากมากจนหาคำตอบลงตัวไม่ได้