ในช่วง 2 ปีที่ผ่านมา ทีมวิศวกรของ Goodnotes ได้ทำโปรเจ็กต์เพื่อนำแอปจดบันทึกที่ประสบความสำเร็จบน iPad ไปไว้ในแพลตฟอร์มอื่นๆ กรณีศึกษานี้ครอบคลุมวิธีที่แอป iPad แห่งปี 2022 เผยแพร่บนเว็บ, ChromeOS, Android และ Windows ที่ขับเคลื่อนโดยเทคโนโลยีเว็บและ WebAssembly โดยใช้โค้ด Swift เดิมที่ทีมพัฒนามามากกว่า 10 ปี
เหตุผลที่ Goodnotes เปิดตัวบนเว็บ, Android และ Windows
ในปี 2021 Goodnotes มีให้บริการเป็นแอปสำหรับ iOS และ iPad เท่านั้น ทีมวิศวกรของ Goodnotes ยอมรับความท้าทายทางเทคนิคครั้งใหญ่ในการสร้าง Goodnotes เวอร์ชันใหม่สำหรับระบบปฏิบัติการและแพลตฟอร์มเพิ่มเติม ผลิตภัณฑ์ควรเข้ากันได้และแสดงผลโน้ตแบบเดียวกับแอปพลิเคชัน iOS อย่างสมบูรณ์ โน้ตที่เขียนทับ PDF หรือรูปภาพที่แนบมาควรมีเนื้อหาที่ตรงกันและแสดงเส้นขีดแบบเดียวกับที่แอป iOS แสดง เส้นที่เพิ่มควรเทียบเท่ากับเส้นที่ผู้ใช้ iOS สร้างขึ้น โดยไม่ขึ้นอยู่กับเครื่องมือที่ผู้ใช้ใช้ เช่น ปากกา ปากกาเน้นข้อความ ปากกาหมึกซึม รูปร่าง หรือยางลบ
จากข้อกำหนดและประสบการณ์ของทีมวิศวกร ทีมได้สรุปอย่างรวดเร็วว่าการนําโค้ด Swift มาใช้ซ้ำจะเป็นแนวทางการดำเนินการที่ดีที่สุด เนื่องจากโค้ดดังกล่าวเขียนขึ้นและทดสอบมาอย่างดีแล้วเป็นเวลาหลายปี แต่เหตุใดจึงไม่พอร์ตแอปพลิเคชัน iOS/iPad ที่มีอยู่ไปยังแพลตฟอร์มหรือเทคโนโลยีอื่น เช่น Flutter หรือ Compose Multiplatform การย้ายไปยังแพลตฟอร์มใหม่จะต้องมีการเขียน Goodnotes ขึ้นใหม่ ซึ่งอาจทำให้เกิดการแข่งขันด้านการพัฒนาแอปพลิเคชัน iOS ที่ใช้อยู่แล้วกับแอปพลิเคชันใหม่ที่กำลังจะสร้างขึ้นจากศูนย์ หรืออาจเกี่ยวข้องกับการหยุดการพัฒนาใหม่ในแอปพลิเคชันที่มีอยู่ขณะที่โค้ดเบสใหม่พัฒนาตามทัน หาก Goodnotes นำโค้ด Swift มาใช้ซ้ำได้ ทีมจะได้รับประโยชน์จากฟีเจอร์ใหม่ที่ทีม iOS นำมาใช้ ขณะที่ทีมข้ามแพลตฟอร์มทํางานเกี่ยวกับพื้นฐานของแอปและทำให้ฟีเจอร์มีความเท่าเทียมกัน
ผลิตภัณฑ์นี้ช่วยแก้ปัญหาที่น่าสนใจหลายประการสำหรับ iOS เพื่อเพิ่มฟีเจอร์ต่างๆ เช่น
- การแสดงผลโน้ต
- การซิงค์เอกสารและโน้ต
- การแก้ไขความขัดแย้งสำหรับโน้ตที่ใช้ประเภทข้อมูลที่จำลองแบบไม่มีความขัดแย้ง
- การวิเคราะห์ข้อมูลสําหรับการประเมินโมเดล AI
- การค้นหาเนื้อหาและการจัดทำดัชนีเอกสาร
- ประสบการณ์การเลื่อนและภาพเคลื่อนไหวที่กําหนดเอง
- ดูการใช้งานโมเดลสําหรับเลเยอร์ UI ทั้งหมด
ทั้งหมดนี้ติดตั้งใช้งานในแพลตฟอร์มอื่นๆ ได้ง่ายขึ้นมากหากทีมวิศวกรสามารถทำให้โค้ดฐาน iOS ทำงานในแอปพลิเคชัน iOS และ iPad อยู่แล้ว และนำไปใช้งานเป็นส่วนหนึ่งของโปรเจ็กต์ที่ Goodnotes สามารถจัดส่งเป็น Windows, Android หรือเว็บแอปพลิเคชันได้
ชุดซอฟต์แวร์โครงสร้างพื้นฐานของ Goodnotes
แต่โชคดีที่เรามีวิธีนำโค้ด Swift ที่มีอยู่มาใช้ซ้ำบนเว็บได้ ซึ่งก็คือ WebAssembly (Wasm) Goodnotes ได้สร้างต้นแบบโดยใช้ Wasm ด้วยโปรเจ็กต์ SwiftWasm แบบโอเพนซอร์สและที่ชุมชนดูแลรักษา เมื่อใช้ SwiftWasm ทีม Goodnotes สามารถสร้างไฟล์ไบนารี Wasm โดยใช้โค้ด Swift ทั้งหมดที่ติดตั้งใช้งานแล้ว ไบนารีนี้อาจรวมอยู่ในหน้าเว็บที่จัดส่งเป็นProgressive Web Application สำหรับ Android, Windows, ChromeOS และระบบปฏิบัติการอื่นๆ ทั้งหมด
โดยมีเป้าหมายเพื่อเปิดตัว Goodnotes เป็น PWA และแสดงใน Store ของทุกแพลตฟอร์ม นอกจาก Swift ซึ่งเป็นภาษาโปรแกรมที่ใช้กับ iOS อยู่แล้ว และ WebAssembly ที่ใช้ในการเรียกใช้โค้ด Swift บนเว็บแล้ว โปรเจ็กต์นี้ยังใช้เทคโนโลยีต่อไปนี้ด้วย
- TypeScript: ภาษาโปรแกรมที่ใช้บ่อยที่สุดสำหรับเทคโนโลยีเว็บ
- React และ webpack: เฟรมเวิร์กและเครื่องมือรวมไฟล์ยอดนิยมสำหรับเว็บ
- PWA และ Service Worker: เครื่องมือที่มีประโยชน์อย่างยิ่งสำหรับโปรเจ็กต์นี้ เนื่องจากทีมสามารถจัดส่งแอปของเราเป็นแอปพลิเคชันแบบออฟไลน์ที่ทำงานได้เหมือนแอป iOS อื่นๆ และคุณสามารถติดตั้งจาก Store หรือเบราว์เซอร์ได้
- PWABuilder: โปรเจ็กต์หลักที่ Goodnotes ใช้เพื่อรวม PWA ไว้ในไบนารีของ Windows แบบเนทีฟเพื่อให้ทีมเผยแพร่แอปของเราจาก Microsoft Store ได้
- กิจกรรมบนเว็บที่เชื่อถือได้: เทคโนโลยี Android ที่สําคัญที่สุดที่บริษัทใช้เพื่อเผยแพร่ PWA ของเราเป็นแอปพลิเคชันเนทีฟ
รูปภาพต่อไปนี้แสดงสิ่งที่ติดตั้งใช้งานโดยใช้ TypeScript แบบคลาสสิกและ React และสิ่งที่ติดตั้งใช้งานโดยใช้ SwiftWasm และ JavaScript, Swift และ WebAssembly เวอร์ชันปกติ ส่วนนี้ของโปรเจ็กต์ใช้ JSKit ซึ่งเป็นไลบรารีการทำงานร่วมกันของ JavaScript สําหรับ Swift และ WebAssembly ที่ทีมใช้เพื่อจัดการ DOM ในหน้าจอเครื่องมือแก้ไขจากโค้ด Swift เมื่อจําเป็น หรือแม้แต่ใช้ API บางรายการสําหรับเบราว์เซอร์โดยเฉพาะ
เหตุผลที่ควรใช้ Wasm และเว็บ
แม้ว่า Apple จะไม่รองรับ Wasm อย่างเป็นทางการ แต่ทีมวิศวกรของ Goodnotes คิดว่าแนวทางนี้เป็นการตัดสินใจที่ดีที่สุดด้วยเหตุผลต่อไปนี้
- การใช้โค้ดซ้ำมากกว่า 100,000 บรรทัด
- ความสามารถในการพัฒนาผลิตภัณฑ์หลักต่อไปขณะที่มีส่วนร่วมในแอปข้ามแพลตฟอร์ม
- ความสามารถในการเข้าถึงทุกแพลตฟอร์มโดยเร็วที่สุดโดยใช้กระบวนการพัฒนาแบบซ้ำ
- มีสิทธิ์ควบคุมการแสดงผลเอกสารเดียวกันโดยไม่ต้องทำตรรกะทางธุรกิจซ้ำทั้งหมด และไม่ต้องทำให้เกิดความแตกต่างในการใช้งาน
- รับประโยชน์จากการปรับปรุงประสิทธิภาพทั้งหมดที่ทำในแพลตฟอร์มทุกแพลตฟอร์มพร้อมกัน (และการแก้ไขข้อบกพร่องทั้งหมดที่ติดตั้งใช้งานในแพลตฟอร์มทุกแพลตฟอร์ม)
การนำโค้ดกว่า 100, 000 บรรทัดและตรรกะทางธุรกิจมาใช้ซ้ำ รวมถึงการใช้ไปป์ไลน์การแสดงผลของเราเป็นพื้นฐาน ในขณะเดียวกัน การทำโค้ด Swift ให้ใช้งานร่วมกับเครื่องมืออื่นๆ ได้จะช่วยให้นักพัฒนาแอปนำโค้ดนี้ไปใช้ซ้ำในแพลตฟอร์มต่างๆ ในอนาคตได้หากจำเป็น
การพัฒนาผลิตภัณฑ์แบบวนซ้ำ
ทีมใช้แนวทางแบบซ้ำๆ เพื่อให้ผู้ใช้ได้รับสิ่งใหม่ๆ เร็วที่สุด Goodnotes เริ่มต้นด้วยผลิตภัณฑ์เวอร์ชันอ่านอย่างเดียว ซึ่งผู้ใช้สามารถรับเอกสารที่แชร์และอ่านจากแพลตฟอร์มใดก็ได้ เพียงมีลิงก์ บุตรหลานก็จะเข้าถึงและอ่านโน้ตเดียวกับที่เขียนจาก iPad ได้ ระยะถัดไปคือการเพิ่มฟีเจอร์การแก้ไขเพื่อให้เวอร์ชันข้ามแพลตฟอร์มเทียบเท่ากับเวอร์ชัน iOS
ผลิตภัณฑ์เวอร์ชันแรกแบบอ่านอย่างเดียวใช้เวลาพัฒนา 6 เดือน ส่วนอีก 9 เดือนต่อมาเราทุ่มเทพัฒนาฟีเจอร์การแก้ไขกลุ่มแรกและหน้าจอ UI ที่คุณใช้ตรวจสอบเอกสารทั้งหมดที่สร้างหรือมีคนแชร์กับคุณได้ นอกจากนี้ ฟีเจอร์ใหม่ของแพลตฟอร์ม iOS ยังพอร์ตไปยังโปรเจ็กต์ข้ามแพลตฟอร์มได้ง่ายด้วย SwiftWasm Toolchain ตัวอย่างเช่น มีการสร้างปากกาชนิดใหม่และนำไปใช้งานข้ามแพลตฟอร์มได้ง่ายๆ โดยใช้โค้ดหลายพันบรรทัดซ้ำ
การสร้างโปรเจ็กต์นี้ถือเป็นประสบการณ์ที่น่าทึ่งและ Goodnotes ได้เรียนรู้สิ่งต่างๆ มากมายจากโปรเจ็กต์นี้ ด้วยเหตุนี้ ส่วนต่อไปนี้จึงจะเน้นไปที่ประเด็นทางเทคนิคที่น่าสนใจเกี่ยวกับการพัฒนาเว็บ การใช้งาน WebAssembly และภาษาต่างๆ เช่น Swift
อุปสรรคเบื้องต้น
การทำงานในโปรเจ็กต์นี้มีความท้าทายมากจากหลายๆ มุมมอง อุปสรรคแรกที่เราพบเกี่ยวข้องกับเครื่องมือของ SwiftWasm เครื่องมือนี้เป็นเครื่องมือที่มีประโยชน์อย่างยิ่งสำหรับทีม แต่โค้ด iOS บางรายการใช้ร่วมกับ Wasm ไม่ได้ ตัวอย่างเช่น โค้ดที่เกี่ยวข้องกับ IO หรือ UI เช่น การติดตั้งใช้งานมุมมอง ไคลเอ็นต์ API หรือการเข้าถึงฐานข้อมูล ไม่สามารถนํากลับมาใช้ซ้ำได้ ทีมจึงต้องเริ่มรีแฟกทอริงบางส่วนของแอปเพื่อให้นํากลับมาใช้ซ้ำจากโซลูชันข้ามแพลตฟอร์มได้ PR ส่วนใหญ่ที่ทีมสร้างขึ้นเป็นการรีแฟกทอริงเพื่อทำให้เป็นการพึ่งพาแบบนามธรรม เพื่อให้ทีมแทนที่ PR เหล่านั้นในภายหลังได้โดยใช้การฉีดข้อมูลการพึ่งพาหรือกลยุทธ์อื่นๆ ที่คล้ายกัน เดิมทีโค้ด iOS ผสมผสานตรรกะทางธุรกิจดิบที่ใช้ได้ใน Wasm กับโค้ดที่รับผิดชอบอินพุต/เอาต์พุตและอินเทอร์เฟซผู้ใช้ซึ่งใช้ไม่ได้ใน Wasm เนื่องจาก Wasm ไม่รองรับ ดังนั้นจึงต้องมีการนำโค้ด IO และ UI ไปใช้ใหม่ใน TypeScript เมื่อตรรกะทางธุรกิจของ Swift พร้อมที่จะนําไปใช้ซ้ำระหว่างแพลตฟอร์ม
แก้ปัญหาด้านประสิทธิภาพแล้ว
เมื่อ Goodnotes เริ่มพัฒนาเครื่องมือแก้ไข ทีมได้พบปัญหาบางอย่างเกี่ยวกับประสบการณ์การแก้ไข และข้อจำกัดทางเทคโนโลยีที่ท้าทายก็เข้ามาอยู่ในแผนของเรา ปัญหาแรกเกี่ยวข้องกับประสิทธิภาพ JavaScript เป็นภาษาแบบเธรดเดียว ซึ่งหมายความว่ามีกองซ้อนการเรียก 1 กองและกองหน่วยความจํา 1 กอง โดยจะเรียกใช้โค้ดตามลําดับและต้องเรียกใช้โค้ดแต่ละส่วนให้เสร็จสิ้นก่อนจึงจะเรียกใช้โค้ดถัดไปได้ การดำเนินการเป็นแบบเรียลไทม์ แต่บางครั้งก็อาจเป็นอันตรายได้ เช่น หากฟังก์ชันใช้เวลาสักครู่ในการแสดงผลหรือต้องรอบางอย่าง ทุกอย่างจะหยุดทำงานในระหว่างนี้ และนี่เป็นสิ่งที่วิศวกรต้องแก้ปัญหา การประเมินเส้นทางที่เฉพาะเจาะจงบางเส้นทางในโค้ดเบสของเราซึ่งเกี่ยวข้องกับเลเยอร์การแสดงผลหรืออัลกอริทึมที่ซับซ้อนอื่นๆ เป็นปัญหาสำหรับทีม เนื่องจากอัลกอริทึมเหล่านี้เป็นแบบซิงค์ และการดำเนินการจะบล็อกเธรดหลัก ทีม Goodnotes เขียนโค้ดใหม่เพื่อให้ทำงานได้เร็วขึ้น และเขียนโค้ดใหม่บางส่วนเพื่อให้เป็นแบบไม่พร้อมกัน นอกจากนี้ ยังเปิดตัวกลยุทธ์อัตราผลตอบแทนเพื่อให้แอปหยุดการเรียกใช้อัลกอริทึมและดำเนินการต่อในภายหลังได้ ซึ่งจะช่วยให้เบราว์เซอร์อัปเดต UI และหลีกเลี่ยงการทิ้งเฟรม การดำเนินการนี้ไม่ใช่ปัญหาสําหรับแอปพลิเคชัน iOS เนื่องจากแอปพลิเคชันสามารถใช้เธรดและประเมินอัลกอริทึมเหล่านี้ในเบื้องหลังได้ขณะที่เธรดหลักของ iOS อัปเดตอินเทอร์เฟซผู้ใช้
โซลูชันอีกอย่างหนึ่งที่ทีมวิศวกรต้องแก้ปัญหาคือการย้ายข้อมูล UI ตามองค์ประกอบ HTML ที่แนบมากับ DOM ไปยัง UI เอกสารตาม Canvas แบบเต็มหน้าจอ โปรเจ็กต์เริ่มแสดงโน้ตและเนื้อหาทั้งหมดที่เกี่ยวข้องกับเอกสารโดยเป็นส่วนหนึ่งของโครงสร้าง DOM โดยใช้องค์ประกอบ HTML เช่นเดียวกับที่หน้าเว็บอื่นๆ แสดง แต่ในระยะหนึ่งได้ย้ายข้อมูลไปยังแคนวาสแบบเต็มหน้าจอเพื่อปรับปรุงประสิทธิภาพในอุปกรณ์ระดับล่างโดยการลดเวลาที่เบราว์เซอร์ใช้ในการอัปเดต DOM
ทีมวิศวกรระบุว่าการเปลี่ยนแปลงต่อไปนี้เป็นสิ่งที่อาจช่วยลดปัญหาบางอย่างที่พบได้ หากทำตั้งแต่เริ่มโครงการ
- เพิ่มการถ่ายโอนภาระงานออกจากชุดข้อความหลักโดยใช้ Web Worker บ่อยๆ สําหรับอัลกอริทึมที่หนัก
- ใช้ฟังก์ชันที่ส่งออกและฟังก์ชันที่นําเข้าแทนไลบรารีการทำงานร่วมกันของ JS-Swift ตั้งแต่เริ่มต้น เพื่อให้ลดผลกระทบด้านประสิทธิภาพของการออกจากบริบท Wasm ได้ ไลบรารีการทำงานร่วมกันของ JavaScript นี้มีประโยชน์ในการเข้าถึง DOM หรือเบราว์เซอร์ แต่ทำงานช้ากว่าฟังก์ชันที่ส่งออกของ Wasm ดั้งเดิม
- ตรวจสอบว่าโค้ดอนุญาตให้ใช้
OffscreenCanvas
อยู่เบื้องหลังเพื่อให้แอปสามารถถ่ายโอนเธรดหลักและย้ายการใช้งาน Canvas API ทั้งหมดไปยังเว็บเวิร์กเกอร์เพื่อเพิ่มประสิทธิภาพของแอปพลิเคชันสูงสุดเมื่อเขียนโน้ต - ย้ายการดำเนินการทั้งหมดที่เกี่ยวข้องกับ Wasm ไปยัง Web Worker หรือแม้แต่กลุ่ม Web Worker เพื่อให้แอปลดภาระงานของชุดข้อความหลักได้
เครื่องมือแก้ไขข้อความ
ปัญหาที่น่าสนใจอีกอย่างหนึ่งเกี่ยวข้องกับเครื่องมือหนึ่งๆ โดยเฉพาะ ซึ่งเป็นเครื่องมือแก้ไขข้อความ
การติดตั้งใช้งาน iOS สําหรับเครื่องมือนี้อิงตาม NSAttributedString
ซึ่งเป็นชุดเครื่องมือขนาดเล็กที่ใช้ RTF อยู่เบื้องหลัง อย่างไรก็ตาม การใช้งานนี้ใช้ร่วมกับ SwiftWasm ไม่ได้ ทีมข้ามแพลตฟอร์มจึงต้องสร้างโปรแกรมแยกวิเคราะห์ที่กำหนดเองตามไวยากรณ์ RTF ก่อน จากนั้นจึงใช้ประสบการณ์การแก้ไขโดยเปลี่ยน RTF เป็น HTML และในทางกลับกัน ในระหว่างนี้ ทีม iOS ก็เริ่มดำเนินการติดตั้งใช้งานใหม่สำหรับเครื่องมือนี้ โดยแทนที่การใช้ RTF ด้วยรูปแบบที่กำหนดเองเพื่อให้แอปแสดงข้อความที่มีการจัดรูปแบบในลักษณะที่ใช้งานง่ายสำหรับแพลตฟอร์มทั้งหมดที่ใช้โค้ด Swift เดียวกัน
ปัญหานี้เป็นหนึ่งในประเด็นที่น่าสนใจที่สุดในแผนงานของโปรเจ็กต์เนื่องจากมีการแก้ปัญหาแบบซ้ำๆ ตามความต้องการของผู้ใช้ ปัญหานี้เกี่ยวข้องกับวิศวกรรมและแก้ไขโดยใช้แนวทางที่มุ่งเน้นผู้ใช้ โดยทีมต้องเขียนโค้ดบางส่วนขึ้นใหม่เพื่อให้แสดงผลข้อความได้ จึงเปิดใช้การแก้ไขข้อความในรุ่นที่ 2
รุ่นที่เผยแพร่แบบวนซ้ำ
การพัฒนาของโปรเจ็กต์ในช่วง 2 ปีที่ผ่านมานั้นน่าทึ่งมาก ทีมเริ่มทําโปรเจ็กต์เวอร์ชันอ่านอย่างเดียว และอีกหลายเดือนต่อมาก็ได้เปิดตัวเวอร์ชันใหม่ที่มีความสามารถในการแก้ไขได้มากมาย ทีมตัดสินใจที่จะใช้ Flag ฟีเจอร์อย่างแพร่หลายเพื่อเผยแพร่การเปลี่ยนแปลงโค้ดไปยังเวอร์ชันที่ใช้งานจริงบ่อยครั้ง ในทุกรุ่น ทีมสามารถเปิดใช้ฟีเจอร์ใหม่และเผยแพร่การเปลี่ยนแปลงโค้ดที่ใช้ฟีเจอร์ใหม่ซึ่งผู้ใช้จะเห็นในอีกไม่กี่สัปดาห์ อย่างไรก็ตาม ทีมคิดว่ายังมีสิ่งที่ปรับปรุงได้ พวกเขาคิดว่าการเปิดตัวระบบ Flag ฟีเจอร์แบบไดนามิกจะช่วยเร่งกระบวนการต่างๆ ได้ เนื่องจากจะไม่จำเป็นต้องมีการทําให้การเผยแพร่ใหม่เพื่อเปลี่ยนค่า Flag วิธีนี้จะช่วยให้ Goodnotes มีความยืดหยุ่นมากขึ้นและยังช่วยเร่งการนำฟีเจอร์ใหม่ไปใช้ได้อีกด้วย เนื่องจาก Goodnotes ไม่จำเป็นต้องลิงก์การนำโปรเจ็กต์ไปใช้กับรุ่นผลิตภัณฑ์
การทำงานแบบออฟไลน์
หนึ่งในฟีเจอร์หลักที่ทีมพัฒนาคือการสนับสนุนแบบออฟไลน์ ความสามารถในการแก้ไขและปรับเปลี่ยนเอกสารเป็นฟีเจอร์ที่คุณคาดหวังจากแอปพลิเคชันลักษณะนี้ แต่ฟีเจอร์นี้ไม่ใช่ฟีเจอร์ง่ายๆ เนื่องจาก Goodnotes รองรับการทำงานร่วมกัน ซึ่งหมายความว่าการเปลี่ยนแปลงทั้งหมดที่ผู้ใช้รายต่างๆ ทำในอุปกรณ์ต่างๆ ควรปรากฏในอุปกรณ์ทุกเครื่องโดยที่ไม่ต้องขอให้ผู้ใช้แก้ไขข้อขัดแย้งใดๆ Goodnotes แก้ปัญหานี้ไปนานแล้วโดยใช้ CRDT อยู่เบื้องหลัง ประเภทข้อมูลที่ซ้ำกันแบบไม่มีความขัดแย้งเหล่านี้ช่วยให้ Goodnotes รวมการเปลี่ยนแปลงทั้งหมดที่ทำในเอกสารโดยผู้ใช้คนใดก็ได้ และผสานการเปลี่ยนแปลงดังกล่าวโดยไม่เกิดข้อขัดแย้งในการผสาน การใช้ IndexedDB และพื้นที่เก็บข้อมูลที่มีให้สำหรับเว็บเบราว์เซอร์เป็นปัจจัยสําคัญที่ช่วยให้ผู้ใช้ได้รับประสบการณ์การทำงานร่วมกันแบบออฟไลน์บนเว็บ
นอกจากนี้ การเปิดเว็บแอป Goodnotes จะทำให้เกิดค่าใช้จ่ายในการดาวน์โหลดครั้งแรกประมาณ 40 MB เนื่องจากขนาดไบนารีของ Wasm ในตอนแรก ทีม Goodnotes อาศัยแคชของเบราว์เซอร์ปกติสำหรับ App Bundle และแอปปลายทาง API ส่วนใหญ่ที่ใช้ แต่ตอนนี้มองย้อนกลับไปแล้ว ทีมน่าจะใช้ประโยชน์จาก Cache API และ Service Worker ที่เชื่อถือได้มากกว่าได้ตั้งแต่เนิ่นๆ ตอนแรกทีมหลีกเลี่ยงงานนี้เนื่องจากคิดว่ามีความซับซ้อน แต่สุดท้ายก็พบว่า Workbox ทำให้งานง่ายขึ้นมาก
คําแนะนําเมื่อใช้ Swift บนเว็บ
หากคุณมีแอปพลิเคชัน iOS ที่มีโค้ดจำนวนมากที่ต้องการนำกลับมาใช้ใหม่ โปรดเตรียมตัวให้พร้อมเนื่องจากคุณกำลังจะเริ่มต้นเส้นทางที่น่าทึ่ง ต่อไปนี้เป็นเคล็ดลับที่คุณอาจสนใจก่อนเริ่มต้น
- ตรวจสอบรหัสที่ต้องการใช้ซ้ำ หากมีการใช้ตรรกะทางธุรกิจของแอปฝั่งเซิร์ฟเวอร์ คุณอาจต้องการนําโค้ด UI มาใช้ซ้ำ และ Wasm จะไม่ช่วยคุณในเรื่องนี้ ทีมได้พิจารณา Tokamak ซึ่งเป็นเฟรมเวิร์กที่ใช้ร่วมกับ SwiftUI ได้สำหรับการสร้างแอปเบราว์เซอร์ด้วย WebAssembly เพียงสั้นๆ แต่เฟรมเวิร์กดังกล่าวยังไม่พร้อมใช้งานมากพอสำหรับความต้องการในแอป อย่างไรก็ตาม หากแอปของคุณมีตรรกะทางธุรกิจหรืออัลกอริทึมที่มีประสิทธิภาพซึ่งเป็นส่วนหนึ่งของโค้ดไคลเอ็นต์ Wasm จะเป็นตัวเลือกที่ดีที่สุด
- ตรวจสอบว่าโค้ดฐาน Swift พร้อมใช้งาน รูปแบบการออกแบบซอฟต์แวร์สําหรับเลเยอร์ UI หรือสถาปัตยกรรมที่เฉพาะเจาะจงซึ่งแยกตรรกะ UI ออกจากตรรกะทางธุรกิจอย่างชัดเจนจะมีประโยชน์อย่างยิ่งเนื่องจากคุณจะนําการใช้งานเลเยอร์ UI มาใช้ซ้ำไม่ได้ สถาปัตยกรรมแบบสะอาดหรือหลักการของสถาปัตยกรรมหกเหลี่ยมก็ถือเป็นพื้นฐานเช่นกัน เนื่องจากคุณจะต้องแทรกและระบุข้อกําหนดของโค้ดที่เกี่ยวข้องกับ IO ทั้งหมด และการดำเนินการจะง่ายขึ้นมากหากคุณใช้สถาปัตยกรรมเหล่านี้ซึ่งรายละเอียดการใช้งานจะกำหนดเป็นนามธรรมและใช้หลักการการกลับรายการการพึ่งพาอย่างแพร่หลาย
- Wasm ไม่มีโค้ด UI ดังนั้น ให้เลือกเฟรมเวิร์ก UI ที่ต้องการใช้กับเว็บ
- JSKit จะช่วยคุณผสานรวมโค้ด Swift กับ JavaScript แต่โปรดทราบว่าหากคุณมีเส้นทางที่ใช้งานบ่อย การข้ามบริดจ์ JS-Swift อาจใช้ทรัพยากรมากและคุณจะต้องแทนที่บริดจ์ด้วยฟังก์ชันที่ส่งออก ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำงานของ JSKit ได้ในเอกสารประกอบอย่างเป็นทางการและโพสต์การค้นหาสมาชิกแบบไดนามิกใน Swift สุดยอดเทคนิคที่ซ่อนอยู่
- คุณจะนําสถาปัตยกรรมกลับมาใช้ใหม่ได้หรือไม่นั้นขึ้นอยู่กับสถาปัตยกรรมที่แอปใช้และไลบรารีกลไกการเรียกใช้โค้ดแบบอะซิงโครนัสที่คุณใช้ รูปแบบต่างๆ เช่น MVVP หรือสถาปัตยกรรมแบบคอมโพสิเบิลจะช่วยให้คุณนําโมเดลมุมมองและตรรกะ UI บางส่วนมาใช้ซ้ำได้โดยไม่ต้องเชื่อมโยงการใช้งานกับข้อกําหนดของ UIKit ที่คุณใช้กับ Wasm ไม่ได้ โปรดทราบว่า RXSwift และไลบรารีอื่นๆ อาจใช้ร่วมกับ Wasm ไม่ได้ คุณจึงต้องใช้ OpenCombine, การทำงานแบบแอสซิงค์/รอ และสตรีบมในโค้ด Swift ของ Goodnotes
- บีบอัดไฟล์ Wasm โดยใช้ gzip หรือ Brotli โปรดทราบว่าขนาดของไฟล์ไบนารีจะค่อนข้างใหญ่สำหรับเว็บแอปพลิเคชันแบบคลาสสิก
- แม้ว่าคุณจะใช้ Wasm ได้โดยไม่มี PWA แต่อย่าลืมใส่ Service Worker อย่างน้อย 1 รายการ แม้ว่าเว็บแอปจะไม่มีไฟล์ Manifest หรือไม่ต้องการให้ผู้ใช้ติดตั้งก็ตาม Service Worker จะบันทึกและแสดงไฟล์ Wasm แบบไม่เสียค่าใช้จ่ายและทรัพยากรทั้งหมดของแอปเพื่อให้ผู้ใช้ไม่ต้องดาวน์โหลดทุกครั้งที่เปิดโปรเจ็กต์
- โปรดทราบว่าการจ้างงานอาจเป็นเรื่องยากกว่าที่คิด คุณอาจต้องจ้างนักพัฒนาเว็บที่เก่งและมีประสบการณืด้าน Swift บ้าง หรือนักพัฒนา Swift ที่เก่งและมีประสบการณืด้านเว็บบ้าง หากหาวิศวกรทั่วไปที่มีความรู้เกี่ยวกับทั้ง 2 แพลตฟอร์มได้ก็เยี่ยมไปเลย
สรุป
การสร้างโปรเจ็กต์เว็บโดยใช้สแต็กเทคโนโลยีที่ซับซ้อนขณะทํางานกับผลิตภัณฑ์ที่เต็มไปด้วยความท้าทายเป็นประสบการณ์ที่ยอดเยี่ยม เส้นทางนี้อาจยาก แต่คุ้มค่าแน่นอน Goodnotes คงไม่สามารถเปิดตัวเวอร์ชันสำหรับ Windows, Android, ChromeOS และเว็บขณะพัฒนาฟีเจอร์ใหม่ๆ สำหรับแอปพลิเคชัน iOS ได้หากไม่ใช้แนวทางนี้ แพลตฟอร์มเทคโนโลยีนี้และทีมวิศวกรของ Goodnotes ทำให้ Goodnotes พร้อมให้บริการในทุกที่ และทีมก็พร้อมที่จะรับมือกับปัญหาใหม่ๆ ต่อไป หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับโปรเจ็กต์นี้ คุณสามารถดูการบรรยายของทีม Goodnotes ที่ NSSpain 2023 อย่าลืมลองใช้ Goodnotes สำหรับเว็บ