ต่อจากตรงที่ค้างไว้
บทความก่อนหน้า จบลงที่คะแนน 60/100 พร้อมรายการปัญหาที่วิเคราะห์ได้ 4 ข้อ และสัญญาว่าจะกลับมาแก้
วันนี้เราแก้แล้ว — deploy แล้ว — และรัน Lighthouse ใหม่แล้ว
ผลลัพธ์ดีกว่าที่คาด
4 สิ่งที่แก้ไป ใน 1 commit
| # | ปัญหา | วิธีแก้ |
|---|---|---|
| 1 | Redirect chain 12.4 วินาที | จัดการ redirect ที่ infrastructure layer |
| 2 | JavaScript โหลดทุกอย่างพร้อมกัน | แยกโหลดเฉพาะส่วนที่ผู้ใช้เห็นก่อน |
| 3 | รูปภาพ PNG ขนาดใหญ่ | แปลง 7 รูปเป็น format ที่เบากว่า |
| 4 | Preload รูปทุกหน้า | เอาออก เหลือเฉพาะรูปที่หน้านั้นต้องใช้จริง |
ไม่มีการ refactor ใหญ่ ไม่มีการเปลี่ยน infrastructure ไม่มีการเพิ่ม CDN ใหม่ แค่แก้สิ่งที่รู้ว่าผิด
ผลลัพธ์ — ตัวเลขจริง
คะแนนรวม
| Metric | ก่อน | หลัง |
|---|---|---|
| Performance | 60 | 86 (best run), median 80–82 |
| Accessibility | — | 91 |
| Best Practices | — | 96 |
| SEO | — | 92 |
Core Web Vitals
| Metric | ก่อน | หลัง | เปลี่ยนแปลง |
|---|---|---|---|
| FCP | 1.6s (0.95) | 1.3s (0.98) | ▼ 0.3s |
| LCP | 9.1s (0.01) | 4.1s (0.46) | ▼ 5.0s |
| TBT | 570ms (0.52) | 90ms (0.99) | ▼ 480ms |
| CLS | 0 (1.0) | 0 (1.0) | ไม่เปลี่ยน |
| Speed Index | 2.8s (0.96) | 1.6s (1.0) | ▼ 1.2s |
| TTI | 9.6s (0.29) | 4.2s (0.86) | ▼ 5.4s |
ตัวเลขอื่นที่เปลี่ยนไป
| Metric | ก่อน | หลัง |
|---|---|---|
| Redirect chain | 12.4s (2 hops) | 0 |
| Main thread work | 3.1s | 1.1s |
| Bootup time | 0.9s | 0.3s |
| Unused JS savings | 300ms potential | 150ms potential |
ตัวเลขที่น่าดีใจที่สุดไม่ใช่คะแนน 86 — แต่คือ TBT ที่ลดจาก 570ms เหลือ 90ms เพราะนั่นหมายความว่า หน้าเว็บตอบสนองได้เร็วขึ้นจริง ๆ ในมุมของผู้ใช้
สิ่งที่เราทำ — และทำไมมันได้ผล
1. ตัด Redirect Chain — สิ่งที่ส่งผลมากที่สุด
ปัญหาเดิม: เมื่อผู้ใช้เข้า enersys.co.th/ เกิด redirect chain 2 hops ที่กิน 12.4 วินาที ก่อนที่ browser จะเริ่มโหลดหน้าจริง
สิ่งที่ทำ: ปรับ infrastructure configuration ให้จัดการ root path โดยตรง — ผู้ใช้ที่เข้า / ได้รับเนื้อหาใน 1 hop แทนที่จะเป็น 2 hop + meta-refresh
ผลลัพธ์: LCP ลดจาก 9.1s เหลือ 4.1s — redirect chain หายไปทั้งหมด
บทเรียน: redirect chain ที่ซ่อนอยู่ใน infrastructure ชั้นนอก คือปัญหาที่ performance audit ตรวจจับได้ แต่ดูจาก code อย่างเดียวตรวจไม่เจอ — ต้องอ่าน Network waterfall ด้วยตาเอง
2. แยกโหลด JavaScript — โหลดเฉพาะสิ่งที่จำเป็น
ปัญหาเดิม: components ขนาดใหญ่ 3 ตัวที่อยู่ด้านล่างของหน้าถูกโหลดพร้อมกับ initial bundle ทั้ง ๆ ที่ผู้ใช้ยังไม่เห็น
สิ่งที่ทำ: แยก 3 components ออกจาก initial bundle ให้โหลดเมื่อผู้ใช้ scroll ลงไปถึง
ผลลัพธ์: TBT ลดจาก 570ms เหลือ 90ms, bootup time ลดจาก 0.9s เหลือ 0.3s — initial bundle เล็กลง JavaScript ที่ต้อง parse และ execute ลดลงทันที
3. แปลงรูปภาพให้เบาลง 62%
ปัญหาเดิม: รูปภาพ 7 รูปยังเป็น PNG ที่ยังไม่ได้ optimize
สิ่งที่ทำ: แปลงทั้งหมดเป็น modern format
ผลลัพธ์:
| เปรียบเทียบ | ก่อน | หลัง | ลดลง |
|---|---|---|---|
| รวม 7 รูป | 588KB | 221KB | 62% |
ประหยัดได้ 367KB ต่อ pageload — โดยที่คุณภาพภาพไม่ต่างกันในทางปฏิบัติ
4. เอา Global Preload ออก — เมื่อ "เตรียมพร้อม" กลายเป็นภาระ
ปัญหาเดิม: ทุกหน้าของเว็บ preload รูป 8 รูปพร้อมกัน — รวมถึงรูปที่หน้านั้นไม่ได้ใช้เลย
ทำไมถึงเป็นปัญหา? Preload hint บอก browser ให้ดึงรูปมาก่อนเลย แต่ถ้าทุกหน้า preload รูป 8 รูป → แย่ง bandwidth กับ resources ที่จำเป็นจริง ๆ → หน้าโหลดช้า
สิ่งที่ทำ: ลบทั้งหมด เหลือเฉพาะ hero image ไว้ในหน้า homepage เท่านั้น
ผลลัพธ์: หน้าอื่น ๆ ไม่ต้องแบกภาระ preload รูปที่ไม่ต้องการ — ลดงานในช่วง initial load ได้มาก
Bonus: Performance Guard ใน CI/CD Pipeline
การแก้ปัญหาครั้งเดียวไม่พอ เพราะ feature ใหม่ทุกตัว, library ใหม่ทุกตัว, รูปใหม่ทุกรูป ล้วนมีโอกาสทำให้คะแนนตกกลับมาโดยไม่มีใครรู้ตัว
เราแก้เรื่องนี้ด้วยวิธีเดียวกับที่แก้ bug — ใส่ automated test เข้าไปใน CI/CD pipeline ถ้าคะแนนตก build จะ fail ทันที
ทำไมต้องมี
"สิ่งที่ไม่ถูกวัด จะไม่ถูกปรับปรุง — และสิ่งที่ถูกวัดแต่ไม่ถูกเตือน จะค่อย ๆ ถดถอยโดยไม่รู้ตัว"
ปัญหาที่ทุกทีมเจอ:
- Performance regression แบบค่อยเป็นค่อยไป — ทุกสัปดาห์เพิ่ม feature เล็กน้อย พอผ่านไป 3 เดือน คะแนนตกจาก 90 เหลือ 60 โดยไม่มีใครสังเกต
- สิ่งที่ดีบนเครื่อง dev อาจแย่สำหรับ user — developer ทดสอบบนเครื่องเร็ว network เร็ว แต่ user จริงอาจใช้ mobile กับ 4G
- SEO ได้รับผลกระทบโดยไม่รู้ตัว — Google ใช้ Core Web Vitals เป็นส่วนหนึ่งของ search ranking ถ้า LCP เกิน 4 วินาที ไม่ใช่แค่ user ไม่พอใจ — Google ก็จัดอันดับให้ต่ำลง
สิ่งที่ performance guard ช่วยได้:
- ตรวจจับ regression ทันที — PR ที่ทำให้คะแนนตกจะถูก block ก่อน merge
- Budget enforcement — กำหนด threshold ชัดเจน ถ้าไม่ถึง pipeline จะ error
- Historical tracking — เก็บรายงานทุกครั้ง เห็นแนวโน้มชัดเจน
- สร้างวัฒนธรรม performance-first — ทุก PR ต้องผ่าน performance check ทีมจะคิดเรื่อง performance ตั้งแต่ตอนเขียน code
ตัวอย่างสถานการณ์จริง
เมื่อเพิ่ม performance guard เข้าไปวันแรก pipeline fail ทันที เพราะ default settings เข้มงวดเกินจริง ต้องการคะแนน 90+ ซึ่งเราอยู่ที่ 73-75 ในสภาพ CI
สิ่งที่ทำคือ ปรับ threshold ให้ตรงกับ baseline จริง แล้วค่อยขยับขึ้นเมื่อแก้ไขจุดอ่อนได้ — pattern ที่แนะนำคือ: เริ่มจาก baseline → ป้องกัน regression → ค่อยยกระดับ ไม่ใช่ตั้ง threshold สูงลิ่วแล้ว skip ทุก build
สิ่งที่ยังต้องปรับปรุง
ตรงไปตรงมา: 86 ดีขึ้นมากจาก 60 แต่ยังไม่ถึงเป้า
LCP ยังอยู่ที่ 4.1 วินาที — เป้าคือ < 2.5 วินาที
LCP ลดลงจาก 9.1s มาเป็น 4.1s ดีขึ้น 55% แต่ Core Web Vitals กำหนดว่า "Good" ต้องต่ำกว่า 2.5s ตอนนี้ยังอยู่ในโซน "Needs Improvement"
สาเหตุน่าจะมาจากวิธีที่ hero image ถูกโหลด — ยังมีโอกาสปรับปรุงได้อีก
Unused CSS ยังเหลือ ~300ms savings potential
ยังมี CSS rules ที่ไม่ได้ใช้หลงเหลืออยู่ การ optimize ให้แม่นขึ้นน่าจะช่วยได้
บทเรียนจากการแก้ครั้งนี้
ข้อ 1: แก้ root cause ไม่ใช่ symptom
ถ้าเราไม่นั่งอ่าน Network waterfall อย่างละเอียดในบทความก่อน เราอาจจะไปเสียเวลา optimize รูปหรือแยก JavaScript โดยไม่รู้ว่า 12.4 วินาทีหายไปกับ redirect chain ที่ infrastructure ชั้นนอก
ข้อ 2: การแก้ infrastructure 1 จุดมีค่ามากกว่า code optimization 100 บรรทัด
LCP ลดจาก 9.1s → 4.1s — ส่วนใหญ่มาจาก redirect ที่หายไป ถ้าต้องเลือกทำอย่างเดียว การแก้ infrastructure ให้ผลลัพธ์มากที่สุด
ข้อ 3: Global preloads เป็น antipattern ที่ดูดีแต่ทำร้ายระบบ
Preload เป็น tool ที่ดีมากเมื่อใช้ถูกที่ แต่ "ถูกที่" หมายความว่า preload เฉพาะ resource ที่ critical สำหรับ หน้านั้น — ไม่ใช่ใส่ทุก resource ไว้ใน layout กลางแล้วหวังว่าจะช่วย
ข้อ 4: วัดผลหลายครั้ง ไม่เชื่อ run เดียว
คะแนนดีสุดคือ 86 แต่ median อยู่ที่ 80–82 Lighthouse มีความแปรปรวน — ดูค่า median มากกว่า best case
สรุป
ใน 1 commit เราปรับปรุงได้:
- Performance Score: 60 → 86 (+43%)
- TBT: 570ms → 90ms (ลด 84%)
- TTI: 9.6s → 4.2s (ลด 56%)
- Main thread work: 3.1s → 1.1s (ลด 65%)
- Bootup time: 0.9s → 0.3s (ลด 67%)
- Redirect chain: 12.4s → 0
- Performance guard ใน CI/CD: คอยเฝ้าไม่ให้คะแนนตกกลับ
ทุกอย่างเกิดขึ้นภายในเวลาไม่ถึง 1 ชั่วโมง ตั้งแต่วิเคราะห์ root cause จนถึง deploy + ยืนยันผลลัพธ์ ไม่มี sprint planning ไม่มี architecture review — แค่อ่าน data ให้เข้าใจแล้วแก้ตรงจุด
เว็บไซต์ขององค์กรคุณเป็นยังไง?
หลายองค์กรที่เราเคยร่วมงานมีปัญหาคล้ายกัน — เว็บไซต์ดูดี ทำงานได้ถูกต้อง แต่ ช้ากว่าที่ควรเป็นหลายเท่า โดยไม่มีใครรู้ เพราะไม่เคยวัด
ปัญหาเหล่านี้ส่งผลจริง:
- Google ลดอันดับ — Core Web Vitals เป็นส่วนหนึ่งของ ranking factor ตั้งแต่ 2021
- ลูกค้าหายไปก่อนเห็นเนื้อหา — 53% ของ mobile users ปิดหน้าเว็บถ้าโหลดนานกว่า 3 วินาที
- Conversion rate ลดลง — ทุก 100ms ที่หน้าโหลดช้าลง conversion ลด 1-2%
สิ่งที่ case study นี้แสดงให้เห็นคือ ปัญหา performance ส่วนใหญ่ไม่ได้ซับซ้อน — แค่ต้องรู้ว่าจะดูตรงไหน
ที่ Enersys เราทำ Web Performance Audit ให้องค์กรที่ต้องการ:
- วิเคราะห์ root cause แบบละเอียด ไม่ใช่แค่ดูคะแนนแล้วเดา
- ตั้ง performance guard ใน pipeline เพื่อป้องกัน regression
- ปรับปรุง Core Web Vitals เพื่อ SEO ranking ที่ดีขึ้น
- วัดผลก่อน-หลังด้วยตัวเลขจริง ไม่ใช่ความรู้สึก
ถ้าอยากรู้ว่าเว็บไซต์ขององค์กรคุณมีปัญหาซ่อนอยู่ตรงไหน — ให้ทีมเราช่วยวิเคราะห์ได้