5 คะแนน โดย GN⁺ 2024-05-05 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

การเดินทางสู่ TypeScript ของ Figma: คอมไพล์ภาษาการเขียนโปรแกรมแบบกำหนดเองให้หายไป

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

จุดเริ่มต้นและข้อจำกัดของภาษา Skew

  • Skew เริ่มต้นเป็นโปรเจกต์เสริมในระยะแรกของ Figma
    • ตอนนั้นจำเป็นต้องสร้างตัวดูตัวอย่างต้นแบบที่รองรับทั้งเว็บและมือถือได้อย่างรวดเร็ว
    • และพัฒนากลายเป็นภาษาคอมไพล์ทั้งชุดเป็น JavaScript ที่ช่วยให้เกิดการปรับแต่งประสิทธิภาพที่สูงขึ้นและลดเวลาคอมไพล์ได้เร็วขึ้น
  • เมื่อเวลาผ่านไปและโค้ด Skew สะสมมากขึ้น ข้อจำกัดก็เริ่มปรากฏชัด
    • บุคคลใหม่อาจปรับตัวได้ยาก
    • ไม่สามารถผสานเข้ากับ codebase อื่นๆ ได้ง่าย
    • ขาด ecosystem ของนักพัฒนานอก Figma
    • ความยากในการขยายมากขึ้นเรื่อยๆ จนเกินข้อดีเดิมของภาษา

ปัจจัยที่ทำให้การย้ายไป TypeScript เป็นไปได้

  • การขยายการรองรับ WebAssembly ในเว็บเบราว์เซอร์มือถือ
  • การแทนที่ส่วนประกอบสำคัญของเอนจิน Skew ด้วยส่วนประกอบที่สอดคล้องในเอนจิน C++
    • ทำให้การย้ายไป TypeScript สูญเสียประสิทธิภาพน้อยลง
  • การเติบโตของทีมทำให้สามารถจัดสรรทรัพยากรเพื่อโฟกัสที่ developer experience ได้

กระบวนการแปลง codebase

  • เป้าหมาย: แปลงโค้ด Skew ทั้งหมดเป็น TypeScript
    • เลือกใช้การย้ายแบบอัตโนมัติแทนการเขียนใหม่ด้วยมือ
    • ป้องกันการชะลอความเร็วในการพัฒนา และป้องกัน runtime error และการลดประสิทธิภาพต่อผู้ใช้
  • กระบวนการ rollout 3 ขั้นตอน
    1. เขียน Skew, build Skew
      • รักษากระบวนการ build เดิม พัฒนา transpiler และเช็คอินโค้ด TS บน GitHub
    2. เขียน Skew, build TypeScript
      • เริ่ม rollout production traffic โดยตรงจาก codebase TypeScript
      • นักพัฒนายังคงเขียน Skew; transpiler จะแปลง Skew เป็น TS
    3. เขียน TypeScript, build TypeScript
      • ทำให้ TS เป็น source of truth สำหรับการพัฒนา
      • ตัดขั้นตอนการสร้างอัตโนมัติและลบโค้ด Skew ออกจาก codebase

หมายเหตุเกี่ยวกับงานของ transpiler

  • คอมไพลเลอร์ประกอบด้วย front-end และ back-end
    • Front-end: วิเคราะห์และทำความเข้าใจซินแทกซ์ของโค้ดต้นทาง ทำการตรวจสอบชนิดข้อมูล และตรวจสอบโครงสร้างประโยค
    • แปลงเป็น IR (Intermediate Representation) เพื่อบันทึก semantics และ logic ของโค้ดต้นทางได้ครบถ้วน
    • Back-end: แปลง IR เป็นภาษาเป้าหมายต่างๆ
  • Transpiler คือคอมไพลเลอร์แบบพิเศษที่สร้างโค้ดที่มนุษย์อ่านได้

ปัญหาที่พบระหว่างการย้าย

  • ประเด็นประสิทธิภาพของ array destructuring
    • หากไม่ใช้ array destructuring ของ JavaScript สามารถเพิ่มประสิทธิภาพได้สูงสุดถึง 25%
  • การปรับแต่ง "devirtualization" ของ Skew
    • ระหว่าง rollout ทำเพิ่มขั้นตอนเพื่อให้แน่ใจว่า devirtualization จะไม่ทำให้พฤติกรรม codebase หยุดชะงัก
  • ใน TypeScript ลำดับการ initialize มีความสำคัญ
    • transpiler ต้องสร้างโค้ดที่เคารพลำดับนี้

ตัวอย่างการใช้ Source Map เพื่อเพิ่มคุณภาพ developer experience

  • Figma มุ่งเน้นให้การย้ายนี้ทำได้ง่ายและช่วยให้ประสบการณ์ดีบักราบรื่นมากขึ้นสำหรับนักพัฒนา
  • เชื่อมโค้ดที่คอมไพล์แล้วเข้ากับโค้ดต้นทางด้วย Source Map
    • เบราว์เซอร์อ่านได้เฉพาะ JavaScript เท่านั้น
    • Source Map ช่วยให้เบราว์เซอร์รู้ว่า breakpoint ใน source code ควรหยุดที่จุดใดใน JavaScript bundle ที่คอมไพล์แล้ว
  • สร้าง Source Map ใน 3 ขั้นตอน
    1. สร้าง Source Map ระหว่าง TypeScript → JavaScript
    2. สร้าง Source Map ระหว่าง Skew → TypeScript สำหรับไฟล์ต้นทาง Skew ทุกไฟล์
    3. ประกอบ Source Map เพื่อสร้างการแมปจาก Skew ไปยัง JavaScript

ตัวอย่างการจัดการ conditional compilation

  • ใน Skew อนุญาตให้คอมไพล์โค้ดเชิงเงื่อนไขด้วยคำสั่ง "if" ระดับบนสุด
    • ใช้ค่าคงที่คอมไพล์เวลาในการกำหนดเงื่อนไข
    • กำหนด build target ที่ต่างกันได้ภายใน codebase เดียวกัน
  • TypeScript ไม่มีความสามารถ conditional compilation
    • ย้ายการทำงานนี้ไปยังขั้นตอน bundling
    • ใช้คุณสมบัติ "defines" และ dead code elimination ของ esbuild
    • มีผลข้างเคียงคือขนาด bundle เพิ่มขึ้นเล็กน้อย

การพัฒนาโปรโตไทป์ในยุค TypeScript

  • ด้วยการย้ายโค้ด Skew ไปยัง TypeScript ทำให้ codebase แกนหลักของ Figma มีความทันสมัยมากขึ้น
    • เปิดทางให้ผสานกับโค้ดภายในและภายนอกได้ง่ายขึ้นมาก
    • ทำให้นักพัฒนาสามารถทำงานได้มีประสิทธิภาพขึ้น
  • ตอนนั้น TypeScript อาจยังไม่เหมาะสม แต่ปัจจุบันเป็นตัวเลือกที่เหมาะสมอย่างชัดเจน
  • กำลังดำเนินงานตามขั้นต่อไปเพื่อรับประโยชน์จากการย้ายไป TypeScript อย่างครบถ้วน
    • การผสานกับ codebase ส่วนที่เหลือ
    • การจัดการแพ็กเกจที่ง่ายขึ้นมาก
    • การใช้ความสามารถใหม่ๆ จาก ecosystem ของ TypeScript โดยตรง เป็นต้น

ความคิดเห็นของ GN⁺

  • Figma ดำเนินการเปลี่ยนจากภาษาการเขียนโปรแกรมแบบกำหนดเองอย่างเป็นระบบและค่อยเป็นค่อยไปไปยัง TypeScript อย่างมีโครงสร้างได้อย่างน่าประทับใจ โดยไม่หยุดการทำงานแม้แต่หนึ่งวันเพื่อย้ายจาก Skew เป็น TypeScript แบบอัตโนมัติ คิดว่าเป็นตัวอย่างที่ดีในการแก้ปัญหาหนี้เทคนิคที่เกิดขึ้นเมื่อองค์กรมีขนาดเพิ่มขึ้นและสอดคล้องกับการเปลี่ยนแปลงของ ecosystem ได้ดี

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

  • การใช้ Source Map เพื่อให้คนทำงานมีประสบการณ์ดีขึ้น และการแก้ปัญหา conditional compilation เป็นแนวทางปฏิบัติที่มีคุณค่ามากในการใช้งานจริง ความสามารถในการย้ายแบบค่อยเป็นค่อยไปพร้อมคงความเข้ากันได้กับ legacy codebase เป็นสิ่งที่น่าประทับใจ

  • สำหรับการย้าย codebase ขนาดใหญ่แบบนี้ ดูเหมือนว่าการมี transpiler สำหรับแปลงโค้ดแบบอัตโนมัติจะเป็นสิ่งจำเป็น การใช้คอมไพเลอร์ Skew เพื่อพัฒนา transpiler น่าจะเป็นกุญแจสำคัญ และเป็นงานที่ต้องอาศัยความเชี่ยวชาญด้านทฤษฎีคอมไพลเลอร์และการออกแบบภายใน

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

1 ความคิดเห็น

 
GN⁺ 2024-05-05
ความคิดเห็นจาก Hacker News
  • Andrew Chan ผู้มีส่วนร่วมในโปรเจกต์ระบุว่า Figma ใช้ TypeScript ในส่วนอื่นมานานเกือบ 10 ปี และในช่วงเวลาส่วนใหญ่ TypeScript มีมากกว่า Skew มาก โดย Skew ใช้เฉพาะในบางพื้นที่ของผลิตภัณฑ์ เช่น เอนจินมือถือ โปรโตไทป์เพลเยอร์ และฟังก์ชันการซิงค์ภาพ

  • ที่น่าทึ่งคือ Figma เคยมีภาษาที่กำหนดเองสำหรับ JavaScript และที่น่าทึ่งกว่านั้นคือมันเร็วกว่าการใช้ TypeScript มาก หลังจากนั้นจึงมีการย้ายมาใช้ TypeScript ซึ่งช้ากว่า

  • Evan Wallace (อดีต CTO ของ Figma) กล่าวว่า Skew เร็วกว่า TypeScript 1.5 ถึง 2 เท่า โดยอาศัยการปรับประสิทธิภาพที่ดีขึ้นซึ่งทำได้ด้วยระบบชนิดข้อมูลที่เคร่งครัดกว่า

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

  • ดูเหมือนว่า Skew จะมีเพียง callback เท่านั้น และมีการกล่าวถึง async/await พร้อมระบบชนิดที่ยืดหยุ่นกว่า

  • Figma สร้าง TypeScript DSL และคอมไพเลอร์เฉพาะตัวเพื่อต้องแก้ปัญหาความปลอดภัย เช่น เรื่องสิทธิ์การเข้าถึง

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

  • อยากรู้จุดประสงค์ที่ทำให้ Figma ใช้ WebAssembly

  • บทเรียนที่ได้: อย่าสร้างภาษากำหนดเอง

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