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

ความพยายามปรับปรุงผ่านแฮกกาธอน

  • ในเดือนมกราคม ทีมได้เก็บข้อมูล เขียนข้อเสนอโปรเจ็กต์สำหรับแฮกกาธอน ทำความเข้าใจระบบ build เดิมให้มากขึ้น และหาวิธีทำ profiling
  • ใช้ OpenTelemetry และ Jaeger เพื่อทำ profiling กระบวนการ build ทั้งหมด
    • ผลการ profiling พบว่า การทำงานของ Webpack/Rollup กินเวลา build ไปเกือบทั้งหมด
    • พบว่า dependency ขนาดเล็กถูก build ทีละตัว จึงมีโอกาสสำหรับการประมวลผลแบบขนานอยู่มาก
    • ยืนยันได้ว่าในช่วงต้นมีงานบางส่วนที่ร้อนจัดใช้เวลานานเกินความจำเป็น จนถ่วงกระบวนการ build ที่เหลือ
  • ระหว่างช่วงแฮกกาธอน ทีมมุ่งเน้นการใช้ esbuild เพื่อลดเวลา bundling
    • ใช้ esbuild เป็น loader ของ Webpack/Rollup เพื่อเพิ่มประสิทธิภาพอย่างมาก (กรณีของ Rollup ลดลง 80%)
    • ใช้ esbuild เป็น bundler ที่เข้ามาแทน Webpack/Rollup ทั้งหมด ทำให้เวลา bundling ลดลง 90%
  • ผลจากโปรเจ็กต์แฮกกาธอน ทำให้เวลา build ของส่วนขยายลดลงมากกว่า 70% เหลือประมาณ 15 วินาที

งานที่ต้องทำเพื่อใช้งานจริงในโปรดักชัน

  • ในโปรเจ็กต์แฮกกาธอนมีการใช้วิธีแก้ชั่วคราวอยู่มาก ดังนั้นหากจะนำไปใช้ในโปรดักชัน จึงต้องแทนที่ด้วยโซลูชันจริง
    • เปลี่ยนจากการใช้ Webpack และ Rollup มาเป็น esbuild ทั้งหมด
    • รวมกระบวนการ build ไว้ในจุดเดียว
    • แก้ปัญหาการจัดการกราฟิกแอสเซ็ต
    • เพิ่มการตรวจสอบ type ของ TypeScript กลับเข้าไปในกระบวนการ build
    • ทดสอบ production build และเปรียบเทียบทั้งขนาดและการทำงาน
    • สะท้อนการเปลี่ยนแปลงของ internal dependency
    • ทำซ้ำองค์ประกอบอื่นของระบบ build เดิม เช่น ขั้นตอน build ของ Sentry
    • เพิ่มการรองรับเบราว์เซอร์ที่ไม่ใช่ Chrome, polyfill และข้อกำหนดการ build เฉพาะของแต่ละสโตร์
  • มีการทำงานโดยเน้นไปที่การตรวจสอบ type และการปรับขนาด production bundle ให้เหมาะสม

เพิ่มการตรวจสอบ type ให้กับ esbuild

  • เนื่องจาก tsc ทำงานช้า จึงใช้งานร่วมกับกระบวนการ build ที่รวดเร็วของ esbuild ได้ยาก
  • ใช้ปลั๊กอินชุมชน esbuild-plugin-typecheck เพื่อรัน tsc บน worker thread และใช้ incremental compilation
  • ทีมได้พัฒนาปลั๊กอินตรวจสอบ type แบบง่ายขึ้นมาเอง เพื่อรันโปรเซส tsc CLI แบบขนานสำหรับแต่ละ package root
    • แปลงข้อความวินิจฉัยการคอมไพล์ของ tsc ให้อยู่ในรูปแบบเนทีฟของ esbuild เพื่อให้อ่านง่ายขึ้น
    • ใช้แฟลก tsc --listFilesOnly และ Metafile ของ esbuild เพื่อตรวจสอบโดยอัตโนมัติว่า input ของ build ทั้งหมดถูกตรวจสอบ type แล้วหรือไม่

ปรับปรุงขนาด production bundle

  • ใช้ตัววิเคราะห์ขนาด bundle ของ esbuild เพื่อวิเคราะห์ production bundle
    • พบปัญหาที่ทั้ง ESM และ CJS build ของไลบรารี UI component ถูกใส่เข้ามาใน bundle พร้อมกัน
    • แก้การตั้งค่าที่ผิดของไลบรารีภายใน ทำให้ขนาด bundle ลดลง (3.3MB -> 2.1MB)
    • ยืนยันผลการลดขนาดไฟล์ในหลาย entrypoint

ผลกระทบและข้อสรุป

  • ผลจากการใช้งานจริงในโปรดักชัน ทำให้เวลา warm build ลดลงมากกว่า 90% เหลือประมาณ 5 วินาที
  • ในโหมด watch สามารถ rebuild ได้ภายใน 1 วินาทีเมื่อมีการเปลี่ยนแปลงไฟล์ TypeScript
  • นักพัฒนาให้ฟีดแบ็กว่าระบบ build ใหม่ช่วยเพิ่มประสิทธิภาพการทำงานอย่างมาก
  • ด้วยความพยายามของทีม QA และอาสาสมัครนักพัฒนา ทำให้การเปลี่ยนผ่านสู่ระบบ build ใหม่เป็นไปอย่างราบรื่น
  • ผลสำรวจความพึงพอใจของนักพัฒนาพบว่า ความไม่พอใจกับเวลา build ลดลงอย่างมากจาก 97% เหลือ 5%
  • esbuild เป็นเครื่องมือที่ยอดเยี่ยม และโปรเจ็กต์แฮกกาธอนก็เหมาะที่สุดสำหรับงานแบบนี้

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น