กลับสู่บล็อก
เทคโนโลยี

เว็บโหลดช้าเพราะรูป กลยุทธ์ optimize image แบบครบวงจรสำหรับ developer ไทย 2026

เผยแพร่เมื่อ8 min read
แชร์

รูปภาพคือปัญหาเบอร์หนึ่งของ Web Performance

ในมุม technical รูปภาพกินสัดส่วนของขนาดเพจยุคใหม่แบบถล่มทลาย ข้อมูล HTTP Archive ธันวาคม 2025 เพจ desktop ขนาด median ~2,312 KB โดยรูปคิดเป็น 1,026 KB (44.4%) บน mobile สัดส่วนสูงกว่า ~47%

แปลว่า ถ้าต้อง optimize แค่ 1 อย่างของเว็บ เลือกรูปภาพ ถูกที่สุด

ที่สำคัญกว่านั้น รูปส่งผลตรงกับ Core Web Vitals ของ Google โดยเฉพาะ LCP (Largest Contentful Paint) จาก CrUX report กว่า 70% ของ LCP element คือรูปหรือ block ที่มี background image LCP เกิน 2.5 วินาที = "Needs Improvement" เกิน 4 วินาที = "Poor" กระทบ SEO ranking โดยตรง

ต่อไปรื้อทีละส่วนในมุม architecture

เคสจริงที่เคยเจอ: LCP พุ่งจาก 1.8 วินาทีเป็น 6.2 วินาที

บอกตามตรง ปีที่แล้วผมรับงานลูกค้าเจ้าหนึ่ง LCP พุ่งจากโซนเขียว (1.8 วินาที) ไปโซนแดง (6.2 วินาที) เพียงแค่เปลี่ยนรูป hero หน้าแรกรูปเดียว ตอนแรกนึกว่า JS bundle ระเบิด debug อยู่ 3 วันถึงเจอ — ดีไซเนอร์คนใหม่อัปโหลด PNG ขนาด 4.5MB ความละเอียด 1920×1080 ขึ้นหน้าแรก ไม่บีบ ไม่มี loading attribute ไม่มี fetchpriority และไม่ผ่าน CDN ทดสอบแล้วพบว่ารูปเดียวนี้เลยที่ฉุด LCP ทั้งหมด

หลังจัดการ 3 เรื่องต่อไปนี้ LCP กลับมาที่ 1.9 วินาที

  1. แปลง PNG เป็น WebP บีบลงเหลือ 180KB (ลดไป 96%)
  2. เติม fetchpriority="high" และ <link rel="preload">
  3. ย้ายรูปขึ้น Cloudflare R2 + Transform Rules ทำ AVIF fallback อัตโนมัติ

กับดักนี้มีคนตกเยอะ พูดตรงๆ รูป hero หน้าแรกคือจุดชี้เป็นชี้ตายของ LCP ขาดอะไรไปสักขั้น Core Web Vitals ทั้งหน้ารายงานเป็นสีแดงทันที แต่ละหัวข้อต่อจากนี้กลั่นมาจากเคสจริงแบบนี้ทั้งนั้น ไม่ได้ก็อปมาจากเอกสาร

Lazy Loading: ชะลอโหลดรูปนอก viewport

Native HTML

วิธีง่ายสุดคือใช้ attribute loading="lazy" ของ browser

<img src="photo.webp" loading="lazy" alt="ตัวอย่างรูป" width="800" height="600">

พื้นฐานคือ browser จะส่ง HTTP request เฉพาะตอนรูปใกล้เข้า viewport Chrome implement ที่ระยะ 1250px (desktop) หรือ 2500px (slow network) ตอนผู้ใช้ scroll ถึงรูปก็โหลดเสร็จแล้ว

ระวัง: รูปใน fold แรก (above the fold) ไม่ควร ตั้ง lazy loading จะทำให้ LCP ช้า รูป above-the-fold ใช้ loading="eager" (default) + fetchpriority="high"

JavaScript: Intersection Observer

ถ้าต้องการควบคุมละเอียดกว่า ใช้ Intersection Observer API

const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
}, { rootMargin: '200px' });

document.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));

ข้อดี — ปรับ trigger distance (rootMargin), ใส่ fade-in animation, หรือ show LQIP (Low Quality Image Placeholder) ก่อนโหลดรูปจริง

เปรียบเทียบ 2 วิธี

หัวข้อ Native loading="lazy" Intersection Observer
Complexity ต่ำมาก (attribute เดียว) กลาง (เขียน JS)
Browser support 95%+ (2026) 97%+
Custom trigger distance ไม่ (browser เลือก) ได้ (rootMargin)
LQIP placeholder ไม่รองรับ รองรับ
SEO ดี (native) ต้อง noscript fallback
Risk ใช้ผิดใน fold แรก มี (ต้อง exclude เอง) exclude ใน code ได้

แนะนำ: เคสส่วนใหญ่ใช้ native พอ ใช้ Intersection Observer เฉพาะเคสที่ต้อง LQIP หรือควบคุมละเอียด

Responsive Images: ให้แต่ละอุปกรณ์โหลดขนาดที่พอ

รูป hero กว้าง 3000px บนมือถือต้องการแค่ 750px ถ้าไม่ทำ responsive images user มือถือโหลดรูปใหญ่เกินไป 4 เท่าเปล่า ๆ

srcset + sizes

<img
  srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w, hero-1600.webp 1600w"
  sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 800px"
  src="hero-800.webp"
  alt="Homepage banner"
>

Browser เลือกรูปเหมาะสุดจาก srcset ตาม viewport width + pixel density sizes บอก browser ว่ารูปกินกว้างเท่าไหร่ใน breakpoint ต่าง ๆ เลือกได้แม่นกว่า

<picture> element: คุม format + art direction

<picture>
  <source srcset="hero.avif" type="image/avif">
  <source srcset="hero.webp" type="image/webp">
  <img src="hero.jpg" alt="Homepage banner">
</picture>

<picture> ส่ง format ต่างกันให้ browser ต่างกัน ใช้ format ที่บีบดีสุดที่ browser รองรับ auto fallback

กลยุทธ์เลือก format

Format ส่งผลตรงกับขนาดไฟล์และคุณภาพ ตัวเลขทดสอบจริง (เงื่อนไข: รูป 1920x1080 เดียวกัน visual quality เทียบเคียง)

Format ขนาดทั่วไป Browser support Transparency Animation เหมาะกับ
JPEG baseline 100% 100% ไม่ ไม่ รูปถ่าย (compat สูงสุด)
WebP ~70% ของ JPEG 97%+ ใช่ ใช่ รูปทั่วไป (แนะนำ default)
AVIF ~50% ของ JPEG 92%+ ใช่ ใช่ รูปถ่าย (compression ดีสุด)
PNG JPEG 300-500% 100% ใช่ ไม่ รูปที่ต้อง transparency
SVG เล็กมาก (vector) 100% ใช่ ใช่ icon, logo, chart

กลยุทธ์แนะนำ: AVIF → WebP → JPEG progressive fallback ใช้ <picture> ให้ browser เลือก auto

CDN และ Caching Strategy

ทำไม CDN สำคัญ

รูปจากเซิร์ฟเวอร์ไทยส่งไปยูเซอร์อเมริกา ระยะทางกาย ~12,000 km ความเร็วแสงใน fiber latency ~40ms (ทางเดียว) บวก TCP handshake, TLS, HTTP request — TTFB (Time To First Byte) ของรูป 1 ใบอาจเกิน 200ms

CDN cache รูปไว้ที่ edge node ทั่วโลก ให้ user ได้ resource จาก node ใกล้สุด CDN ดี ๆ ลด TTFB จาก 200ms+ เหลือ 20-50ms

Cache Header

Cache-Control: public, max-age=31536000, immutable

รูปมักไม่เปลี่ยน ตั้ง cache 1 ปี + immutable บอก browser ไม่ต้อง revalidate ถ้ารูปต้องอัปเดต เปลี่ยนชื่อไฟล์ (hash) เพื่อ invalidate

Image CDN

Cloudflare Images, Imgix, Cloudinary ฯลฯ นอกจาก CDN ปกติ ยังให้

  • Format conversion on-the-fly (auto เลือก AVIF/WebP/JPEG ตาม Accept header)
  • Resize on-the-fly (ใช้ URL parameter กำหนด width/height)
  • Quality auto optimization (ปรับ compression ตาม network speed)

Image Compression Pipeline

ในมุม architecture pipeline ที่สมบูรณ์ประกอบด้วย

  1. Upload-time compression: ใช้ Sharp (Node.js) หรือ Pillow (Python) บีบฝั่ง server
  2. Multi-size generation: สร้าง 3-5 ขนาด (400w, 800w, 1200w, 1600w, original)
  3. Multi-format conversion: ทำ AVIF, WebP, JPEG ทั้ง 3 format สำหรับแต่ละ size
  4. Quality tuning: JPEG quality 75-85, WebP quality 75-80, AVIF quality 60-70
  5. Metadata stripping: ลบ EXIF ลดขนาด + ปกป้อง privacy

ตัวอย่าง รูป 1920x1080 หลังผ่าน pipeline user มือถือโหลดจริงอาจเป็น AVIF 400w ขนาด ~30KB ลดจาก 2MB เป็น ~30KB — ลดการส่ง 98.5%

ผลของ Core Web Vitals

LCP (Largest Contentful Paint)

LCP วัดเวลา render ของ largest visible element สำหรับเพจที่ LCP element คือรูป

  • ดี: ≤ 2.5 วินาที
  • ต้องปรับ: 2.5-4 วินาที
  • แย่: > 4 วินาที

Optimize รูป above-the-fold

  1. fetchpriority="high" เพิ่มความสำคัญของการดาวน์โหลด
  2. <link rel="preload"> preload LCP image
  3. ห้าม lazy load รูปใน fold แรก
  4. รับประกัน cache hit rate ของ CDN

CLS (Cumulative Layout Shift)

ถ้าไม่กันพื้นที่รูปก่อนโหลด layout กระโดด แก้ง่าย: ใส่ width + height ใน <img> เสมอ browser คำนวณ aspect ratio ก่อนรูปโหลดได้

<img src="photo.webp" width="800" height="600" alt="Example">

Checklist Image Optimization

ก่อน launch ตรวจทีละข้อ

  • รูป above-the-fold ตั้ง fetchpriority="high", รูปอื่น loading="lazy"
  • <img> ทุก tag มี width + height
  • ใช้ <picture> ส่ง AVIF/WebP/JPEG fallback
  • ใช้ srcset + sizes ส่งหลายขนาด
  • รูปผ่าน compression JPEG 75-85, WebP 75-80
  • CDN เปิด cache header ถูก (max-age=31536000, immutable)
  • EXIF metadata ถูกลบ
  • LCP image มี <link rel="preload">
  • PageSpeed Insights LCP ≤ 2.5 วินาที

เคสในบริบทไทย

เว็บข่าวไทยยักษ์ใหญ่ (Thairath, Dailynews, Prachachat)

Traffic สูงมาก การ optimize รูปทุก % ประหยัด bandwidth หลักล้านบาทต่อเดือน กลยุทธ์หลักคือ (1) Cloudflare หรือ Akamai CDN (2) image resize โดย backend ล่วงหน้า (3) AVIF + WebP + JPEG fallback (4) lazy load ทุกรูปใน article page ยกเว้นหน้าปก

E-commerce ไทย (Shopee Mall, Lazada Store, ร้านบน WooCommerce)

Product listing page มีรูปหลายสิบรูป lazy loading + responsive images สำคัญมาก แนะนำ Cloudinary หรือ Imgix ที่แปลง format on-the-fly + ปรับ size URL-based

Blog และ Blockdit ของคนไทย

ผู้เขียน content ส่วนใหญ่ไม่มี engineer ช่วยทำ compression pipeline แนะนำ (1) Squoosh บีบก่อนอัป (2) ใช้ image hosting ที่มี CDN ในเอเชีย (เช่น lpic.cc, ImgBB) (3) ถ้าใช้ WordPress ติด plugin เช่น Smush หรือ ShortPixel

LINE OA Landing Page

เพจ Landing จาก Rich Menu ของ LINE OA โหลดในเบราว์เซอร์ภายในแอป ปรับ optimize แบบเว็บทั่วไป + preload รูปหลักเพราะ user อาจปิดก่อนรูปโหลด

ISP ต่าง ๆ ในไทยกับความเร็วโหลดรูป

  • AIS, True: peer กับ Cloudflare/Google ดี รูปจาก CDN โหลดเร็ว
  • 3BB: stability ดี ส่วนใหญ่รูปโหลดปกติ
  • NT: peer กับ Japan ดีพิเศษ ถ้า CDN node Tokyo เร็วเป็นพิเศษ

ดังนั้นเลือก CDN ที่มี node Tokyo หรือ Singapore จะครอบ ISP ไทยทั้งหมด

บทบาทของ Image Hosting

ถ้าไม่อยาก build image pipeline + CDN เอง ใช้ image hosting พร้อมใช้เป็นทางเลือกที่ practical

ตัวอย่าง lpic.cc ให้อัปรูปไม่ต้องสมัคร + CDN global + password protection สำหรับ blog writer และเว็บเล็กในไทย ประหยัดต้นทุน build infrastructure เอง แต่แจ้งว่า lpic.cc ไม่รองรับ API integration และ resize on-the-fly ถ้า project ต้อง batch upload เชิงโปรแกรม หรือ dynamic transform พิจารณา Cloudinary หรือ Imgix

คำถามที่พบบ่อย FAQ

Q1: Lazy loading กระทบ SEO ไหม

ไม่กระทบ Googlebot run JavaScript และ simulate scroll ได้ index รูปที่ใช้ loading="lazy" ถูก แต่ถ้าใช้ custom JavaScript lazy load ใส่ <noscript> fallback เผื่อให้ search engine ตามรูปได้

Q2: WebP กับ AVIF ใช้อันไหน

Compression — AVIF ชนะ (เล็กกว่า JPEG ~50%) แต่ encoding AVIF ช้ากว่า ไม่เหมาะ realtime conversion กลยุทธ์ที่ดีคือใช้ <picture> ส่งทั้งคู่ browser เลือก auto ถ้าเลือกได้แค่ตัวเดียว WebP compatibility สูงกว่า (97% vs 92%) safer

Q3: Image CDN คุ้มค่าใช้จ่ายไหม

ขึ้นกับ traffic ถ้าเพจต่ำกว่า 100K PV/เดือน Cloudflare free plan (มี basic CDN) พอแล้ว เกินนั้น professional image CDN เช่น Imgix หรือ Cloudinary ที่ auto format conversion + resize ลด bandwidth cost ได้ ระยะยาวคุ้ม

Q4: บีบอัดรูปทำให้คุณภาพหายไหม

Lossy compression มี quality loss แน่ แต่ที่ quality setting เหมาะ (JPEG 75-85, WebP 75-80) ตาคนแทบไม่รู้สึก แนะนำวัดด้วย SSIM — SSIM > 0.95 user ส่วนใหญ่แยกก่อน/หลังไม่ออก

Q5: เว็บใช้ CDN แล้ว ยังต้อง optimize รูปอีกไหม

ต้อง CDN แก้แค่ "ระยะส่ง" ไม่แก้ "ปริมาณส่ง" รูป 5MB ที่ไม่ได้ optimize ต่อให้ CDN ใกล้สุดก็ต้องส่ง 5MB format conversion + size adaptation + compression ลด bandwidth ได้ 80-95% ผลกว่าการใช้ CDN อย่างเดียว

Q6: Next.js / Nuxt ในไทย มี image optimization built-in ไหม

Next.js มี <Image> component handle responsive + lazy + format conversion ให้ run บน Vercel ได้ดี deploy บน custom server ต้องตั้ง image optimization service เอง Nuxt 3 มี <NuxtImg> ทำได้คล้าย

Q7: ทำ Shopify theme สำหรับร้านค้าไทย optimize รูปยังไง

Shopify เอง handle responsive และ format conversion (WebP) ใน theme ใหม่ ๆ ใช้ {{ image | image_url: width: 800 }} Liquid helper ได้ srcset + format อัตโนมัติ กับธีมที่ไม่ support ให้ใช้ Shopify Image Optimization app

แหล่งอ้างอิง

#Web Performance#Image Optimization#lazy loading#responsive images#CDN#Core Web Vitals
H

เขียนโดย

Harvey Zhang

ผู้ร่วมก่อตั้ง & CTO

วิศวกร Backend และสถาปนิกระบบ