ป้องกันคำขอเครือข่ายที่ไม่จำเป็นด้วยแคช HTTP

การดึงข้อมูลผ่านเครือข่ายนั้นทั้งช้าและแพง

  • การตอบกลับขนาดใหญ่ต้องมีการส่งข้อมูลไปมาหลายรอบระหว่างเบราว์เซอร์กับเซิร์ฟเวอร์
  • หน้าเว็บจะไม่โหลดจนกว่าทรัพยากรสําคัญทั้งหมดจะดาวน์โหลดเสร็จสมบูรณ์
  • หากผู้ใช้เข้าถึงเว็บไซต์ของคุณด้วยแพ็กเกจอินเทอร์เน็ตมือถือแบบจำกัด คำขอเครือข่ายที่ไม่จำเป็นทุกรายการจะเป็นการสิ้นเปลืองเงินของผู้ใช้

คุณหลีกเลี่ยงคำขอเครือข่ายที่ไม่จำเป็นได้อย่างไร แคช HTTP ของเบราว์เซอร์คือด่านป้องกันแรกของคุณ วิธีการนี้อาจไม่ใช่วิธีที่มีประสิทธิภาพหรือยืดหยุ่นที่สุด และคุณมีการควบคุมที่จำกัดเกี่ยวกับอายุของการตอบสนองที่แคชไว้ แต่วิธีนี้มีประสิทธิภาพ รองรับในเบราว์เซอร์ทุกรุ่น และไม่จําเป็นต้องทํางานมาก

คู่มือนี้จะแสดงข้อมูลเบื้องต้นเกี่ยวกับการใช้งานแคช HTTP ที่มีประสิทธิภาพ

ความเข้ากันได้กับเบราว์เซอร์

จริงๆ แล้วไม่มี API เดียวที่เรียกว่าแคช HTTP ซึ่งเป็นชื่อทั่วไปของคอลเล็กชัน API ของแพลตฟอร์มเว็บ เบราว์เซอร์ทั้งหมดรองรับ API ต่อไปนี้

Cache-Control

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

ETag

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Last-Modified

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

วิธีการทำงานของแคช HTTP

คำขอ HTTP ทั้งหมดที่เบราว์เซอร์ส่งจะได้รับการกําหนดเส้นทางไปยังแคชของเบราว์เซอร์ก่อนเพื่อตรวจสอบว่ามีการตอบกลับที่แคชไว้ซึ่งถูกต้องและสามารถใช้เพื่อตอบสนองคําขอได้หรือไม่ หากตรงกัน ระบบจะอ่านคำตอบจากแคช ซึ่งจะช่วยลดทั้งเวลาในการตอบสนองของเครือข่ายและค่าบริการอินเทอร์เน็ตมือถือที่เกิดจากการโอน

ลักษณะการทํางานของแคช HTTP ควบคุมโดยส่วนหัวคําขอและส่วนหัวการตอบกลับร่วมกัน ในกรณีที่ดีที่สุด คุณจะมีสิทธิ์ควบคุมทั้งโค้ดสําหรับเว็บแอปพลิเคชัน (ซึ่งจะเป็นตัวกําหนดส่วนหัวคําขอ) และการกำหนดค่าของเว็บเซิร์ฟเวอร์ (ซึ่งจะเป็นตัวกําหนดส่วนหัวการตอบกลับ)

อ่านบทความการแคช HTTP ของ MDN เพื่อดูภาพรวมเชิงแนวคิดที่ละเอียดยิ่งขึ้น

ส่วนหัวของคำขอ: ใช้ค่าเริ่มต้น (โดยปกติ)

มีหลายส่วนหัวสำคัญซึ่งควรรวมอยู่ในคำขอขาออกของเว็บแอป แต่เบราว์เซอร์จะเป็นผู้ตั้งค่าส่วนหัวเหล่านี้ในนามของคุณเกือบทุกครั้งที่ส่งคำขอ ส่วนหัวคำขอที่ส่งผลต่อการตรวจสอบความใหม่ เช่น If-None-Match และ If-Modified-Since จะปรากฏขึ้นตามความเข้าใจของเบราว์เซอร์เกี่ยวกับค่าปัจจุบันในแคช HTTP

นี่เป็นข่าวดี เนื่องจากคุณยังคงใส่แท็กอย่าง <img src="my-image.png"> ใน HTML ได้ต่อไป และเบราว์เซอร์จะจัดการแคช HTTP ให้คุณโดยอัตโนมัติโดยไม่ต้องทำอะไรเพิ่มเติม

ส่วนหัวการตอบกลับ: กำหนดค่าเว็บเซิร์ฟเวอร์

ส่วนการตั้งค่าการแคช HTTP ที่สําคัญที่สุดคือส่วนหัวที่เว็บเซิร์ฟเวอร์เพิ่มลงในคําตอบขาออกแต่ละรายการ ส่วนหัวต่อไปนี้ล้วนส่งผลต่อลักษณะการแคชที่มีประสิทธิภาพ

  • Cache-Control เซิร์ฟเวอร์สามารถแสดงคำสั่ง Cache-Control เพื่อระบุวิธีและระยะเวลาที่เบราว์เซอร์และแคชกลางอื่นๆ ควรแคชการตอบกลับแต่ละรายการ
  • ETag เมื่อเบราว์เซอร์พบคำตอบที่แคชไว้ซึ่งหมดอายุแล้ว ก็สามารถส่งโทเค็นขนาดเล็ก (โดยปกติคือแฮชของเนื้อหาไฟล์) ไปยังเซิร์ฟเวอร์เพื่อตรวจสอบว่าไฟล์มีการเปลี่ยนแปลงหรือไม่ หากเซิร์ฟเวอร์แสดงผลโทเค็นเดียวกัน แสดงว่าไฟล์นั้นเหมือนกันและไม่จำเป็นต้องดาวน์โหลดอีกครั้ง
  • Last-Modified ส่วนหัวนี้มีไว้เพื่อวัตถุประสงค์เดียวกับ ETag แต่ใช้กลยุทธ์ตามเวลาเพื่อระบุว่าทรัพยากรมีการเปลี่ยนแปลงหรือไม่ ต่างจากกลยุทธ์ตามเนื้อหาของ ETag

เว็บเซิร์ฟเวอร์บางรุ่นรองรับการตั้งค่าส่วนหัวเหล่านั้นโดยค่าเริ่มต้น ส่วนบางรุ่นจะไม่ใช้ส่วนหัวเลย เว้นแต่คุณจะกําหนดค่าไว้อย่างชัดเจน รายละเอียดที่เฉพาะเจาะจงของวิธีกำหนดค่าส่วนหัวจะแตกต่างกันอย่างมากโดยขึ้นอยู่กับเว็บเซิร์ฟเวอร์ที่คุณใช้ และคุณควรอ่านเอกสารประกอบของเซิร์ฟเวอร์เพื่อให้ได้รายละเอียดที่ถูกต้องที่สุด

ต่อไปนี้เป็นวิธีการกำหนดค่าเว็บเซิร์ฟเวอร์ยอดนิยมบางรายการเพื่อช่วยให้คุณไม่ต้องค้นหา

การไม่ระบุส่วนหัวการตอบกลับ Cache-Control ไม่ได้ปิดใช้การแคช HTTP แต่เบราว์เซอร์จะคาดเดาอย่างมีประสิทธิภาพว่าลักษณะการแคชประเภทใดเหมาะสมกับเนื้อหาประเภทหนึ่งๆ มากที่สุด คุณอาจต้องการการควบคุมมากกว่าที่เครื่องมือนี้มอบให้ ดังนั้นโปรดใช้เวลาในการกําหนดค่าส่วนหัวการตอบกลับ

คุณควรใช้ค่าส่วนหัวของคำตอบใด

มี 2 สถานการณ์สำคัญที่คุณควรพิจารณาเมื่อกำหนดค่าส่วนหัวคำตอบของเว็บเซิร์ฟเวอร์

การแคชเป็นระยะเวลานานสําหรับ URL เวอร์ชัน

สมมติว่าเซิร์ฟเวอร์ของคุณสั่งให้เบราว์เซอร์แคชไฟล์ CSS เป็นเวลา 1 ปี (Cache-Control: max-age=31536000) แต่นักออกแบบเพิ่งทำการอัปเดตฉุกเฉินซึ่งคุณต้องทำให้ใช้งานได้ทันที คุณแจ้งให้เบราว์เซอร์อัปเดตสำเนาที่แคชไว้ซึ่ง "ล้าสมัย" ของไฟล์ได้อย่างไร ไม่ได้ อย่างน้อยก็เปลี่ยนไม่ได้หากไม่เปลี่ยน URL ของทรัพยากร

หลังจากเบราว์เซอร์แคชคำตอบแล้ว ระบบจะใช้เวอร์ชันที่แคชไว้จนกว่าจะไม่ใหม่อีกต่อไปตามที่ max-age หรือ expires กำหนด หรือจนกว่าระบบจะนำออกจากแคชด้วยเหตุผลอื่นๆ เช่น ผู้ใช้ล้างแคชของเบราว์เซอร์ ด้วยเหตุนี้ ผู้ใช้แต่ละรายจึงอาจใช้ไฟล์เวอร์ชันต่างกันเมื่อสร้างหน้าเว็บ ผู้ใช้ที่เพิ่งดึงข้อมูลทรัพยากรจะใช้เวอร์ชันใหม่ ส่วนผู้ใช้ที่แคชสำเนาเวอร์ชันเก่า (แต่ยังคงใช้งานได้) จะใช้การตอบกลับเวอร์ชันเก่า

คุณจะทำให้ได้สิ่งที่ดีที่สุดจากทั้ง 2 โลก ซึ่งก็คือการแคชฝั่งไคลเอ็นต์และการอัปเดตอย่างรวดเร็วได้อย่างไร คุณเปลี่ยน URL ของทรัพยากรและบังคับให้ผู้ใช้ดาวน์โหลดคำตอบใหม่ทุกครั้งที่เนื้อหามีการเปลี่ยนแปลง โดยปกติแล้ว คุณจะทำเช่นนี้โดยการฝังลายนิ้วมือของไฟล์หรือหมายเลขเวอร์ชันไว้ในชื่อไฟล์ เช่น style.x234dff.css

เมื่อตอบกลับคำขอ URL ที่มี "ลายนิ้วมือ" หรือข้อมูลเวอร์ชัน และเนื้อหาที่ไม่ได้มีไว้เพื่อเปลี่ยนแปลง ให้เพิ่ม Cache-Control: max-age=31536000 ในการตอบกลับ

การตั้งค่านี้บอกเบราว์เซอร์ว่าเมื่อต้องโหลด URL เดียวกันทุกเมื่อภายใน 1 ปีข้างหน้า (31,536,000 วินาที ซึ่งเป็นค่าสูงสุดที่รองรับ) เบราว์เซอร์จะใช้ค่าในแคช HTTP ได้ทันทีโดยไม่ต้องส่งคำขอเครือข่ายไปยังเว็บเซิร์ฟเวอร์เลย เยี่ยมมาก คุณจะได้รับความเร็วและความน่าเชื่อถือที่เกิดจากการหลีกเลี่ยงเครือข่ายทันที

เครื่องมือสร้าง เช่น webpack สามารถทำให้กระบวนการกำหนดลายนิ้วมือแฮชให้กับ URL ของชิ้นงานเป็นแบบอัตโนมัติ

การตรวจสอบเซิร์ฟเวอร์อีกครั้งสําหรับ URL ที่ไม่มีเวอร์ชัน

ขออภัย URL ที่คุณโหลดบางรายการไม่มีเวอร์ชัน คุณอาจไม่สามารถรวมขั้นตอนการบิลด์ก่อนทำให้เว็บแอปใช้งานได้ จึงไม่สามารถเพิ่มแฮชลงใน URL ของชิ้นงานได้ และเว็บแอปพลิเคชันทุกรายการต้องใช้ไฟล์ HTML ซึ่งไฟล์เหล่านั้น (แทบ) จะไม่มีข้อมูลเวอร์ชัน เนื่องจากไม่มีใครอยากใช้เว็บแอปของคุณหากต้องจำ URL ที่จะเข้าชมเป็น https://example.com/index.34def12.html คุณจะทำสิ่งใดได้บ้างสำหรับ URL เหล่านั้น

นี่เป็นสถานการณ์หนึ่งที่คุณต้องยอมรับความพ่ายแพ้ แคช HTTP เพียงอย่างเดียวนั้นมีประสิทธิภาพไม่เพียงพอที่จะหลีกเลี่ยงเครือข่ายโดยสิ้นเชิง (ไม่ต้องกังวล ในไม่ช้าคุณจะได้รู้จักService Worker ซึ่งจะให้การสนับสนุนที่เราจําเป็นเพื่อพลิกสถานการณ์ให้กลับมาอยู่ในฝั่งของคุณ) แต่คุณทำตามขั้นตอนบางอย่างเพื่อให้คำขอเครือข่ายรวดเร็วและมีประสิทธิภาพมากที่สุดได้

ค่า Cache-Control ต่อไปนี้จะช่วยคุณปรับแต่งตําแหน่งและวิธีแคช URL ที่ไม่มีเวอร์ชันได้

  • no-cache ซึ่งจะบอกให้เบราว์เซอร์ต้องตรวจสอบกับเซิร์ฟเวอร์อีกครั้งทุกครั้งก่อนที่จะใช้ URL เวอร์ชันที่แคชไว้
  • no-store ซึ่งจะสั่งให้เบราว์เซอร์และแคชสื่อกลางอื่นๆ (เช่น CDN) ไม่ให้จัดเก็บไฟล์เวอร์ชันใดๆ
  • private เบราว์เซอร์จะแคชไฟล์ได้ แต่แคชระดับกลางจะแคชไม่ได้
  • public แคชใดก็ได้สามารถจัดเก็บการตอบกลับได้

ดูภาคผนวก: แผนภาพเวิร์กโฟลว์ Cache-Control เพื่อดูภาพกระบวนการตัดสินใจว่าจะใช้ค่า Cache-Control ใด Cache-Control ยังยอมรับรายการคําสั่งที่คั่นด้วยคอมมาได้ด้วย โปรดดูภาคผนวก: ตัวอย่าง Cache-Control

การตั้งค่าเป็น ETag หรือ Last-Modified ก็ช่วยได้เช่นกัน ดังที่ได้กล่าวไว้ในส่วนหัวของคำตอบ ETag และ Last-Modified มีวัตถุประสงค์เดียวกันคือ ระบุว่าเบราว์เซอร์ต้องดาวน์โหลดไฟล์ที่แคชไว้ซึ่งหมดอายุแล้วอีกครั้งหรือไม่ เราขอแนะนำให้ใช้ ETag เนื่องจากแม่นยำกว่า

สมมติว่าผ่านไป 120 วินาทีนับตั้งแต่การดึงข้อมูลครั้งแรกและเบราว์เซอร์ได้เริ่มคําขอใหม่สําหรับทรัพยากรเดียวกัน ก่อนอื่นเบราว์เซอร์จะตรวจสอบแคช HTTP และค้นหาการตอบกลับก่อนหน้า ขออภัย เบราว์เซอร์ใช้คำตอบก่อนหน้าไม่ได้เนื่องจากคำตอบดังกล่าวหมดอายุแล้ว เมื่อถึงจุดนี้ เบราว์เซอร์จะส่งคําขอใหม่และดึงข้อมูลการตอบกลับแบบเต็มใหม่ได้ แต่วิธีนี้ไม่มีประสิทธิภาพเนื่องจากหากทรัพยากรไม่มีการเปลี่ยนแปลง ก็ไม่มีเหตุผลที่จะดาวน์โหลดข้อมูลเดียวกันที่มีอยู่ในแคชอยู่แล้ว

นั่นคือปัญหาที่โทเค็นการตรวจสอบซึ่งระบุในส่วนหัว ETag ออกแบบมาเพื่อแก้ปัญหา เซิร์ฟเวอร์จะสร้างและแสดงโทเค็นที่กำหนดเอง ซึ่งโดยทั่วไปจะเป็นแฮชหรือลายนิ้วมืออื่นๆ ของเนื้อหาในไฟล์ เบราว์เซอร์ไม่จำเป็นต้องทราบว่าระบบสร้างลายนิ้วมืออย่างไร เพียงแค่ต้องส่งลายนิ้วมือไปยังเซิร์ฟเวอร์ในคำขอครั้งถัดไป หากลายนิ้วมือยังคงเหมือนเดิม แสดงว่าทรัพยากรไม่มีการเปลี่ยนแปลงและเบราว์เซอร์จะข้ามการดาวน์โหลดได้

การตั้งค่า ETag หรือ Last-Modified จะทำให้คำขอตรวจสอบอีกครั้งมีประสิทธิภาพมากขึ้นโดยให้ทริกเกอร์ส่วนหัวคำขอ If-Modified-Since หรือ If-None-Match ที่กล่าวถึงในส่วนหัวคำขอ

เมื่อเว็บเซิร์ฟเวอร์ที่กําหนดค่าอย่างถูกต้องเห็นส่วนหัวคําขอขาเข้าเหล่านั้น ก็จะยืนยันได้ว่าเวอร์ชันของทรัพยากรที่เบราว์เซอร์มีอยู่แล้วในแคช HTTP ตรงกับเวอร์ชันล่าสุดในเว็บเซิร์ฟเวอร์หรือไม่ หากตรงกัน เซิร์ฟเวอร์จะตอบกลับด้วย HTTP Response 304 Not Modified ซึ่งเทียบเท่ากับ "เฮ้ ใช้สิ่งที่คุณมีอยู่แล้วต่อไป" ข้อมูลที่จะโอนมีเพียงเล็กน้อยเมื่อส่งการตอบกลับประเภทนี้ จึงมักจะเร็วกว่าการส่งสําเนาทรัพยากรจริงที่ขอ

ภาพการแสดงผลไคลเอ็นต์ที่ขอทรัพยากรและเซิร์ฟเวอร์ที่ตอบสนองด้วยส่วนหัว 304
เบราว์เซอร์ขอ /file จากเซิร์ฟเวอร์และใส่ส่วนหัว If-None-Match เพื่อสั่งให้เซิร์ฟเวอร์แสดงเฉพาะไฟล์แบบเต็มในกรณีที่ ETag ของไฟล์ในเซิร์ฟเวอร์ไม่ตรงกับค่า If-None-Match ของเบราว์เซอร์ ในกรณีนี้ ค่า 2 ค่าตรงกัน ดังนั้นเซิร์ฟเวอร์จะแสดงการตอบกลับ 304 Not Modified พร้อมวิธีการเกี่ยวกับระยะเวลาที่ควรแคชไฟล์ (Cache-Control: max-age=120)

สรุป

แคช HTTP เป็นวิธีที่มีประสิทธิภาพในการปรับปรุงประสิทธิภาพการโหลดเนื่องจากจะลดคําขอเครือข่ายที่ไม่จําเป็น ฟีเจอร์นี้ใช้ได้กับเบราว์เซอร์ทุกประเภทและตั้งค่าได้ง่าย

การกําหนดค่า Cache-Control ต่อไปนี้เป็นจุดเริ่มต้นที่ดี

  • Cache-Control: no-cache สำหรับทรัพยากรที่ควรตรวจสอบกับเซิร์ฟเวอร์อีกครั้งก่อนใช้งานทุกครั้ง
  • Cache-Control: no-store สำหรับทรัพยากรที่ไม่ควรแคช
  • Cache-Control: max-age=31536000 สำหรับทรัพยากรที่มีเวอร์ชัน

ส่วนส่วนหัว ETag หรือ Last-Modified จะช่วยให้คุณตรวจสอบทรัพยากรแคชที่หมดอายุแล้วอีกครั้งได้อย่างมีประสิทธิภาพมากขึ้น

ดูข้อมูลเพิ่มเติม

หากต้องการทราบข้อมูลนอกเหนือจากพื้นฐานเกี่ยวกับการใช้ส่วนหัว Cache-Control โปรดดูคู่มือแนวทางปฏิบัติแนะนำในการแคชและข้อควรระวังเกี่ยวกับอายุสูงสุดของ Jake Archibald

ดูคำแนะนำเกี่ยวกับวิธีเพิ่มประสิทธิภาพการใช้แคชสําหรับผู้เข้าชมที่กลับมาได้ที่รักแคชของคุณ

ภาคผนวก: เคล็ดลับเพิ่มเติม

หากมีเวลามากขึ้น คุณสามารถใช้วิธีต่อไปนี้เพื่อเพิ่มประสิทธิภาพการใช้แคช HTTP

  • ใช้ URL ที่สอดคล้องกัน หากคุณแสดงเนื้อหาเดียวกันใน URL ที่แตกต่างกัน ระบบจะดึงข้อมูลและจัดเก็บเนื้อหานั้นหลายครั้ง
  • ลดการเลิกใช้งาน หากทรัพยากรบางส่วน (เช่น ไฟล์ CSS) อัปเดตบ่อย แต่ส่วนที่เหลือของไฟล์ไม่อัปเดต (เช่น โค้ดไลบรารี) ให้พิจารณาแยกโค้ดที่อัปเดตบ่อยออกเป็นไฟล์แยกต่างหาก และใช้กลยุทธ์การแคชระยะเวลาสั้นสําหรับโค้ดที่อัปเดตบ่อย และกลยุทธ์การแคชระยะเวลานานสําหรับโค้ดที่ไม่เปลี่ยนแปลงบ่อย
  • ดูคำสั่ง stale-while-revalidate ใหม่หากนโยบาย Cache-Control ของคุณยอมรับข้อมูลล้าสมัยได้ในระดับหนึ่ง

ภาคผนวก: โฟลว์ชาร์ต Cache-Control

โฟลว์ชาร์ต
กระบวนการตัดสินใจในการตั้งค่าส่วนหัว Cache-Control

ภาคผนวก: ตัวอย่าง Cache-Control รายการ

ค่า Cache-Control คำอธิบาย
max-age=86400 เบราว์เซอร์และแคชสื่อกลางสามารถแคชการตอบกลับได้สูงสุด 1 วัน (60 วินาที x 60 นาที x 24 ชั่วโมง)
private, max-age=600 เบราว์เซอร์สามารถแคชการตอบกลับได้ (แต่ไม่ใช่แคชสื่อกลาง) สูงสุด 10 นาที (60 วินาที x 10 นาที)
public, max-age=31536000 แคชใดก็ได้จัดเก็บการตอบกลับได้นาน 1 ปี
no-store ระบบไม่อนุญาตให้แคชคำตอบและต้องดึงข้อมูลทั้งหมดทุกครั้งที่ขอ