คู่มือ HTTP Cache Header Generator: ทำความเข้าใจ Cache-Control, ETag และ Conditional Requests
เรียนรู้วิธีใช้ HTTP Cache Header Generator สร้าง Cache-Control, ETag และ conditional request headers พร้อม presets สำหรับ static assets, APIs และ SPA
Table of Contents
HTTP caching เป็นหนึ่งในเทคนิคที่ให้ผลตอบแทนสูงที่สุดด้าน web performance แต่ก็เป็นอีกอย่างที่พลาดง่ายที่สุดเหมือนกัน Cache-Control ที่ตั้งค่าผิดอาจทำให้ user เห็นราคาสินค้าเก่า หรืออีกด้านหนึ่ง บังคับให้ browser ดาวน์โหลด JavaScript bundle ขนาด 2 MB ที่ไม่เปลี่ยนแปลงใหม่ทุกครั้งที่เข้าเว็บ HTTP Cache Header Generator ช่วยตัดความไม่แน่นอนนี้ออกไป — เลือก preset, ปรับ directives สองสามตัว แล้วได้ header block พร้อม copy ไปใช้ พร้อม nginx config ที่ match กัน
เครื่องมือนี้ครอบคลุมภาพรวมของ caching ทั้งหมด ไม่ใช่แค่ Cache-Control เพราะมัน generate ค่า ETag และ Last-Modified สำหรับ conditional requests ด้วย อธิบาย directives อย่าง stale-while-revalidate แบบ inline และ output เป็น add_header directives ที่ paste ลง nginx ได้ทันที ไม่ว่าคุณจะทำ caching ให้ versioned static assets, API responses หรือ HTML shell ของ SPA ก็มี preset ที่ตรงกับ flow ของคุณ — และคู่มือนี้จะอธิบาย concept เบื้องหลังทุก toggle เพื่อให้คุณเข้าใจว่าทำไมแต่ละ directive ถึงอยู่ใน output
ทำไมต้องใช้ HTTP Cache Header Generator?
- ลดความผิดพลาดจากการเขียน header มือ — Cache-Control syntax ที่ผิดนิดเดียว (เว้นวรรคผิดที่, ใส่ directive ที่ไม่มีอยู่) ทำให้ browser ignore ทั้งบรรทัด เครื่องมือนี้ generate syntax ที่ถูกต้องเสมอ
- Preset สำหรับทุก scenario ที่พบบ่อย — Static Assets, API Response, SPA / HTML, Immutable CDN และ Custom ครอบคลุม use case หลักเกือบทั้งหมดที่ dev เจอใน production
- ได้ทั้ง header block และ nginx config — ไม่ต้องแปลง header เป็น add_header directive เอง ลดขั้นตอนที่เกิด bug ได้
- เรียนรู้ไปพร้อมกับใช้งาน — comments อธิบายทุก directive ใน output ทำให้เข้าใจว่า s-maxage ต่างจาก max-age อย่างไร โดยไม่ต้องเปิด RFC อ่าน
- ทดสอบ caching strategy ได้เร็ว — ปรับ toggle แล้วเห็น header เปลี่ยนแบบ real-time ก่อนเอาไปใช้จริง
- ใช้ฟรี 100% ในเบราว์เซอร์ — ไม่ต้อง sign up ไม่ต้องติดตั้งอะไร ทำงานได้ทันที
ฟีเจอร์เด่น
| ฟีเจอร์ | รายละเอียด |
|---|---|
| One-click presets | Static Assets, API Response, SPA / HTML, Immutable CDN, Custom |
| Cache-Control builder | ปรับ max-age, s-maxage, public/private, immutable, must-revalidate |
| Stale-while-revalidate | เปิดใช้พร้อมค่า 86400 วินาที พร้อมคำอธิบายการทำงาน |
| Validators | สร้าง ETag และ Last-Modified สำหรับ conditional requests |
| Nginx config output | ได้ add_header directives พร้อม location blocks สำหรับทุก preset |
| Copy-to-clipboard | คัดลอก header block ไปใช้ได้ในคลิกเดียว |
Preset แต่ละตัวปรับ controls ให้อัตโนมัติ — เลือก Static Assets แล้ว max-age จะกระโดดไปที่ 31536000 วินาที (1 ปี) พร้อม immutable และเปิด ETag ให้ ส่วน preset SPA / HTML จะตั้งเป็น no-cache เพื่อให้ HTML เช็ค origin ทุกครั้ง แต่ให้ assets ที่ fingerprint แล้วใช้ cache ยาว
ส่วน Nginx output จะแยกตาม preset จริง เช่น static preset ให้ add_header Cache-Control พร้อม etag on ใน location block ของ /assets/ ทำให้เอาไปวางใน server block ได้ทันที
วิธีใช้งาน
- เปิด HTTP Cache Header Generator ในเบราว์เซอร์
- เลือก preset ที่ตรงกับชนิดของ content — เริ่มจาก Static Assets ถ้าไม่แน่ใจ
- ปรับ directives ตามต้องการ เช่น เปลี่ยน max-age, เพิ่ม s-maxage สำหรับ CDN หรือเปิด stale-while-revalidate
- สลับ ETag และ Last-Modified ตามที่ origin server รองรับ
- กด copy เอา header block ไปใช้ หรือคัดลอก nginx config ไปวางใน server block
เข้าใจ HTTP Caching ให้ลึกซึ้ง
max-age vs s-maxage
max-age=N บอก browser (และ shared cache ที่ไม่ได้ตั้งค่าแยก) ว่า response สดใหม่นานเท่าไร วินาที ส่วน s-maxage=N override ค่านี้เฉพาะ shared cache อย่าง CDN — ทำให้ตั้งให้ CDN เก็บนาน 1 ชั่วโมง แต่ browser เก็บแค่ 60 วินาทีได้ ตัวอย่างที่พบบ่อยคือ API ที่ข้อมูลเปลี่ยนบ่อย แต่อยากลด load ที่ origin:
Cache-Control: public, max-age=60, s-maxage=3600
ETag และ If-None-Match
ETag เป็น fingerprint ของ resource เช่น "abc123def456" เมื่อ cache หมดอายุ browser ส่ง If-None-Match: "abc123def456" กลับไป ถ้า resource ไม่เปลี่ยน origin ตอบ 304 Not Modified แทนตัวไฟล์ — ประหยัด bandwidth เต็มๆ สำหรับไฟล์ใหญ่นี่คือความต่างระหว่างโหลด 2 MB กับ header ไม่กี่ร้อย byte
Last-Modified และ If-Modified-Since
Last-Modified ทำงานแบบเดียวกันแต่อิง timestamp แทน hash — browser ส่ง If-Modified-Since และ origin ตอบ 304 ถ้าไฟล์ไม่ได้แก้ไขหลังจากวันนั้น ETag แม่นยำกว่าเพราะตรวจ content จริง แต่ Last-Modified มีประโยชน์เมื่อ server ไม่สร้าง ETag ให้ ใช้ทั้งคู่ไปพร้อมกันได้ (browser จะเช็ค ETag ก่อน)
304 Not Modified: กลไกประหยัด bandwidth
Conditional request ทั้งระบบนี้เรียกว่า revalidation — cache หมดอายุไม่ได้แปลว่าต้องโหลดใหม่ทั้งไฟล์ แค่ต้อง "ถาม" origin ว่าของเดิมยังใช้ได้ไหม ถ้าตอบ 304 ก็ต่ออายุ cache ต่อไป นี่คือเหตุผลที่ควรเปิด ETag เสมอเมื่อ max-age สั้น
stale-while-revalidate
Directive นี้แก้ปัญหา "cache หมดอายุ = user รอ" — stale-while-revalidate=86400 อนุญาตให้ serve content เก่า (stale) ไปก่อน พร้อมกับ fetch ของใหม่ใน background คำขอถัดไปจะได้ของสด ประสบการณ์ของ user ต่อเนื่องไม่มีจังหวะสะดุด เหมาะกับ API ที่ data เก่ากว่า 1 วันไม่เป็นไร
immutable คืออะไร
ไฟล์ที่มี content hash ในชื่อ อย่าง app.a3f9c2.js จะไม่มีวันเปลี่ยน content ตรง URL เดิม — deploy ใหม่คือ URL ใหม่ สำหรับไฟล์แบบนี้ immutable บอก browser ว่าไม่ต้อง revalidate เลยแม้ user กด refresh ทำให้ reload หน้าเว็บเร็วขึ้นมาก
no-cache vs no-store
สองตัวนี้คนสับสนบ่อยที่สุด — no-cache ไม่ได้ห้าม cache! มันห้าม "ใช้ cache โดยไม่ revalidate" คือเก็บได้แต่ต้องเช็ค ETag ก่อนทุกครั้ง ส่วน no-store คือห้ามเก็บเลยจริงๆ สำหรับ HTML ของ SPA ใช้ no-cache (เพื่อให้ user ได้ deploy ล่าสุดเร็วที่สุด) ส่วนข้อมูลอ่อนไหนอย่าง token ใช้ no-store
Browser cache vs CDN cache
สอง layer นี้ทำงานด้วยกฎเดียวกัน (อ่าน Cache-Control เหมือนกัน) แต่เป็น cache คนละใบ — browser เก็บต่อ user คนเดียว ส่วน CDN edge เก็บแชร์กันทั้ง region เมื่อคุณใช้ s-maxage คุณกำลังพูดกับ CDN โดยเฉพาะ และ purge cache ของ CDN ต้องทำผ่าน dashboard/API ของ CDN เอง ลบใน browser ไม่ช่วย
Use cases ในทางปฏิบัติ
Static assets ที่มี versioned filenames
Build tool สมัยใหม่ (Vite, webpack, Next.js) ต่อท้าย hash ให้ไฟล์อัตโนมัติ — นี่คือโอกาสทองของ aggressive caching:
Cache-Control: public, max-age=31536000, immutable
เลือก preset Static Assets ในเครื่องมือแล้วได้ header นี้พร้อม nginx block สำหรับ /assets/ ทันที ผลคือ visitor ที่กลับมาโหลดไฟล์เหล่านี้จาก disk cache เลย ไม่มี network request เลย
API responses ที่ข้อมูลเปลี่ยนปานกลาง
สำหรับ API อย่าง product listing ที่อัปเดตทุกชั่วโมง แต่ค่าไม่จำเป็นต้องสดแบบ real-time — ใช้ no-cache ร่วมกับ ETag เพื่อให้ client เช็คทุกครั้งแต่จ่ายแค่ 304 ถ้าไม่มีอะไรเปลี่ยน หรือถ้ายอมรอ 1 นาทีได้ ใช้ max-age=60 บวก stale-while-revalidate เพื่อกัน burst traffic
SPA: HTML กับ JS bundles ต้องคนละกฎ
จุดพลาดคลาสสิกของ SPA คือตั้ง cache เหมือนกันทั้งเว็บ — HTML ต้องเป็น no-cache เพื่อให้ user ได้ index.html เวอร์ชันใหม่ที่อ้าง hash ไฟล์ใหม่ แต่ไฟล์ JS/CSS ที่ถูก fingerprint แล้วต้อง cache ยาว + immutable ถ้ากลับกัน (HTML cache ยาว) user จะติดเวอร์ชันเก่าหลัง deploy ไปหลายชั่วโมง preset SPA / HTML ในเครื่องมือแยกกฎให้ตามนี้พอดี
CDN edge caching ลด load ที่ origin
เมื่อ traffic กระจายหลาย region การตั้ง s-maxage=86400 ให้ edge nodes เก็บ response ไว้ 1 วัน ช่วยให้ origin โดน hit แค่ครั้งแรกต่อ region ต่อวัน — เหมาะกับหน้า marketing, sitemap, หรือ API สาธารณะที่ไม่เชื่อมกับ user session อยากให้ browser สดกว่านั้นก็ตั้ง max-age สั้นกว่า s-maxage ได้
Best Practices
- Fingerprint ก่อน แล้วค่อย cache ยาว — immutable + 1 ปี ปลอดภัยเฉพาะเมื่อชื่อไฟล์เปลี่ยนทุกครั้งที่ content เปลี่ยน
- HTML ต้อง revalidate เสมอ — ใช้ no-cache กับ entry point ของเว็บ ไม่ใช่ no-store (ยังกินประโยชน์จาก 304 ได้)
- เปิด ETag/Last-Modified ทุกครั้งที่ max-age สั้น — revalidation ฟรีไม่มีข้อเสีย และประหยัด bandwidth มหาศาล
- อย่าใช้ no-store กับของที่ไม่ sensitive — มันเป็น powerful แต่ throw away ประโยชน์ของ caching ทั้งหมด เก็บไว้กับ response ที่มีข้อมูลส่วนบุคคลจริงๆ
- ตั้ง s-maxage ให้ CDN แยกจาก max-age ของ browser — ควบคุมได้ว่าแต่ละ layer สดแค่ไหน ตามความถี่ที่ data เปลี่ยนและ pattern การเข้าถึง
- ทดสอบ header จริงหลัง deploy — ใช้ curl -I เช็คว่า header ที่ออกจริงตรงกับที่ตั้งไว้ เพราะ CDN หรือ middleware บางตัว override ค่าโดยไม่แจ้ง
เริ่มต้นสร้าง Cache Headers ที่ถูกต้องวันนี้
Caching ที่ตั้งค่าดีทำให้เว็บเร็วขึ้นแบบรับรู้ได้ทันที, ลด cost ที่ origin และ CDN และยังเป็น core web vital (LCP ที่ดี) ที่ Google ใช้จัดอันดับด้วย ทุกอย่างเริ่มจาก header ที่ถูกต้อง — และตอนนี้คุณเข้าใจแล้วว่าแต่ละ directive ทำอะไร
ลองเปิด HTTP Cache Header Generator เลือก preset ที่ตรงกับโปรเจกต์ ปรับค่าสองสามตัว แล้วเอา header และ nginx config ไปใช้ได้เลย — ใช้เวลาไม่ถึงนาที แต่ผลลัพธ์อยู่กับเว็บคุณไปนาน
เครื่องมือที่เกี่ยวข้อง
ขอให้สนุกกับการทำ caching!