13 คะแนน โดย whatsup 2025-02-10 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

บทความนี้อธิบายการแก้ปัญหาหน้าจอขาวที่เกิดจากการไม่สามารถโหลดไฟล์สแตติกระหว่างการดีพลอยด้วย AWS S3 + CloudFront หวังว่าจะเป็นประโยชน์สำหรับผู้ที่กำลังมองหาแนวทางดีพลอยไฟล์สแตติกอย่างเสถียรด้วย AWS S3 + CloudFront

[ที่มาของปัญหา]

  • ให้บริการ Frontend ที่พัฒนาด้วย React + Vite
  • หลังดีพลอยเกิดหน้าจอขาวเป็นบางครั้ง → ไม่สามารถโหลดไฟล์สแตติกได้
  • ข้อผิดพลาดในคอนโซล: MIME type ไม่ตรงกัน (ส่งคืน text/html)

[การวิเคราะห์ปัญหา]

  • MIME type ไม่ตรงกัน: ส่งคืน HTML response แทนไฟล์สแตติก
  • สมมติฐานว่า Github Actions ถูกยกเลิก → ECS instance ถูกลบออก
  • ช่วงเวลาการดีพลอยกับการเสิร์ฟไฟล์สแตติกไม่สอดคล้องกัน
  • index.html ของเวอร์ชันเดิมอ้างอิงไฟล์สแตติกใหม่ แต่ไฟล์ถูกลบไปแล้ว

[วิธีแก้ไข]

  • ใช้ CloudFront + S3 (ตัดสินใจสุดท้าย)
  • ใช้ absolute path ของ S3 เพื่อคงไฟล์สแตติกของเวอร์ชันก่อนหน้าไว้
  • ตอน build ด้วย Vite เพิ่ม commitHash, timestamp ในชื่อไฟล์ → รักษาความเป็นเอกลักษณ์
  • ตั้งค่า S3 Lifecycle เพื่อลบไฟล์ที่ไม่จำเป็นโดยอัตโนมัติ
  • เชื่อมต่อกับ CloudFront เพื่อเสิร์ฟไฟล์สแตติกได้รวดเร็วและเสถียร
  • แยกการตั้งค่าสำหรับสภาพแวดล้อม Local, Dev, Prod

[ผลการตรวจสอบ]

  • ยืนยันว่าการใช้ CloudFront + S3 ทำงานได้ตามปกติ
  • ใช้กลยุทธ์แคช: ตรวจสอบ browser cache (Cache-Control, max-age)
  • เมื่อกำหนดความเป็นเอกลักษณ์ให้ไฟล์แล้ว จึงไม่จำเป็นต้องทำ cache invalidation
  • สามารถดีพลอยได้อย่างเสถียรโดยไม่มีปัญหาไฟล์สแตติกหายเหมือนก่อนหน้า

[สิ่งที่ได้เรียนรู้]

  • การจัดการไฟล์สแตติกในสภาพแวดล้อมการดีพลอยอาจส่งผลต่อ UX อย่างมาก
  • เมื่อตรวจสอบสมมติฐาน แนวทางที่รวดเร็วและเรียบง่ายมีความสำคัญ
  • ได้ประสบการณ์ในการปรับสภาพแวดล้อมการดีพลอยให้เหมาะสมด้วย S3 + CloudFront
  • จำเป็นต้องแยกกลยุทธ์การดีพลอยตามแต่ละสภาพแวดล้อม (Local, Dev, Prod)
  • ต้องเข้าใจการทำงานของ browser caching (Cache-Control, from disk cache) อย่างถูกต้อง

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

 
cnaa97 2025-02-10

ก็เป็นปัญหาอยู่แล้วเพราะเป็นการทำ rolling deployment แค่ทำให้เวลา deploy สั้นลง หรือแยกการ deploy แล้วใช้กลยุทธ์ blue-green เพื่อเททราฟฟิกไปฝั่งเดียวก็ได้

หรือจะดักจับ error ของ React แล้วบังคับให้ reload ก็ได้เหมือนกัน