การดึงข้อมูลทรัพยากรผ่านเครือข่ายนั้นช้าและมีค่าใช้จ่ายสูง
- การตอบกลับขนาดใหญ่ต้องมีการส่งข้อมูลไปกลับหลายครั้งระหว่างเบราว์เซอร์และเซิร์ฟเวอร์
- หน้าของคุณจะไม่โหลดจนกว่าทรัพยากรที่สำคัญทั้งหมดจะได้รับการดาวน์โหลดอย่างสมบูรณ์
- หากมีคนเข้าถึงเว็บไซต์ของคุณด้วยแพ็กเกจอินเทอร์เน็ตมือถือที่จำกัด ทุกคำขอเครือข่ายที่ไม่จำเป็นถือเป็นการสิ้นเปลืองเงิน
คุณจะหลีกเลี่ยงคำขอเครือข่ายที่ไม่จำเป็นได้อย่างไร แคช HTTP ของเบราว์เซอร์คือด่านแรกในการป้องกันของคุณ วิธีนี้อาจไม่ใช่วิธีที่มีประสิทธิภาพหรือยืดหยุ่นที่สุด และคุณควบคุมอายุการใช้งานของคำตอบที่แคชไว้ได้อย่างจำกัด แต่ก็มีประสิทธิภาพเพราะรองรับการใช้งานในเบราว์เซอร์ทั้งหมด และไม่ต้องลงแรงมากนัก
คู่มือนี้แสดงข้อมูลเบื้องต้นเกี่ยวกับการใช้งานการแคช HTTP ที่มีประสิทธิภาพ
ความเข้ากันได้กับเบราว์เซอร์
จริงๆ แล้วไม่มี API ตัวเดียวที่เรียกว่า แคช HTTP เป็นชื่อทั่วไปสำหรับคอลเล็กชันของ API ของแพลตฟอร์มเว็บ มีการรองรับ API ดังกล่าวในทุกเบราว์เซอร์ ดังนี้
Cache-Control
ETag
Last-Modified
วิธีการทำงานของแคช 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 ที่มี "fingerprint" หรือข้อมูลการกำหนดเวอร์ชัน ซึ่งเนื้อหาดังกล่าวจะไม่มีการเปลี่ยนแปลง ให้เพิ่ม 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 เพียงอย่างเดียวไม่มีประสิทธิภาพมากพอที่จะหลีกเลี่ยงเครือข่ายได้โดยสมบูรณ์ (ไม่ต้องกังวล คุณจะได้เรียนรู้เกี่ยวกับโปรแกรมทำงานของบริการในเร็วๆ นี้ ซึ่งจะให้การสนับสนุนที่เราต้องการเพื่อพลิกโฉมการต่อสู้ให้เป็นประโยชน์กับคุณ) แต่มี 2-3 ขั้นตอนที่คุณสามารถทำตามเพื่อให้คำขอเครือข่ายรวดเร็วและมีประสิทธิภาพมากที่สุด
ค่า 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 304 Not Modified
ซึ่งเทียบเท่ากับข้อความ "สวัสดี ใช้สิ่งที่คุณมีอยู่แล้วต่อไป" เมื่อส่งการตอบกลับประเภทนี้ จะมีข้อมูลจำนวนน้อยมาก ดังนั้นจึงมักจะเร็วกว่าการส่งสำเนาของทรัพยากรจริงที่ขอกลับมา
สรุป
แคช HTTP เป็นวิธีที่มีประสิทธิภาพในการปรับปรุงประสิทธิภาพการโหลด เนื่องจากจะลดคำขอของเครือข่ายที่ไม่จำเป็น ได้รับการสนับสนุนในทุกเบราว์เซอร์และไม่ต้องตั้งค่ามากนัก
การกำหนดค่า Cache-Control
ต่อไปนี้เป็นจุดเริ่มต้นที่ดี
Cache-Control: no-cache
สำหรับทรัพยากรที่ควรตรวจสอบความถูกต้องอีกครั้งกับเซิร์ฟเวอร์ก่อนการใช้งานทุกครั้งCache-Control: no-store
สำหรับทรัพยากรที่ไม่ควรแคชCache-Control: max-age=31536000
สำหรับทรัพยากรที่มีเวอร์ชัน
และส่วนหัว ETag
หรือ Last-Modified
จะช่วยให้คุณตรวจสอบทรัพยากรแคชที่หมดอายุได้อีกครั้งได้อย่างมีประสิทธิภาพมากขึ้น
ดูข้อมูลเพิ่มเติม
หากต้องการใช้ส่วนหัว Cache-Control
มากกว่าพื้นฐาน โปรดดูคู่มือแนวทางปฏิบัติแนะนำในการแคชและ M-age Gotchas ของ Jake Archibald
โปรดดูที่ชอบแคชของคุณเพื่อดูคำแนะนำเกี่ยวกับวิธีเพิ่มประสิทธิภาพการใช้แคชสำหรับผู้เข้าชมที่กลับมา
ภาคผนวก: เคล็ดลับเพิ่มเติม
หากคุณมีเวลาเพิ่มเติม คุณสามารถเพิ่มประสิทธิภาพการใช้งานแคช HTTP ได้หลายวิธีดังนี้
- ใช้ URL ที่สอดคล้องกัน หากคุณแสดงเนื้อหาเดียวกันใน URL ต่างกัน ระบบจะดึงข้อมูลและจัดเก็บเนื้อหานั้นหลายครั้ง
- ลดการเลิกใช้งาน หากส่วนหนึ่งของทรัพยากร (เช่น ไฟล์ CSS) อัปเดตบ่อยๆ ในขณะที่ไฟล์ที่เหลือไม่มีการอัปเดต (เช่น โค้ดไลบรารี) ให้พิจารณาแบ่งโค้ดที่อัปเดตบ่อยๆ เป็นไฟล์แยกต่างหากและใช้กลยุทธ์การแคชระยะเวลาสั้นๆ สำหรับโค้ดที่อัปเดตบ่อยๆ และใช้กลยุทธ์ระยะเวลาการแคชที่ยาวนานสำหรับโค้ดที่ไม่มีการเปลี่ยนแปลงบ่อยๆ
- ดูคำสั่ง
stale-while-revalidate
ใหม่ หากระบบยอมรับการไม่มีอัปเดตในระดับใดระดับหนึ่งในนโยบาย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 |
ระบบไม่อนุญาตให้แคชการตอบกลับและต้องดึงข้อมูลทั้งหมดในคำขอทุกรายการ |