ทำความเข้าใจกับส่วนหัวที่แตกต่างกัน

เผยแพร่แล้ว: 2022-03-10
สรุปอย่างย่อ ↬ ส่วนหัว Vary HTTP ถูกส่งไปในการตอบสนอง HTTP หลายพันล้านครั้งทุกวัน แต่การใช้งานไม่เคยบรรลุตามวิสัยทัศน์เดิม และนักพัฒนาหลายคนเข้าใจผิดว่ามันทำอะไรหรือไม่รู้ด้วยซ้ำว่าเว็บเซิร์ฟเวอร์ของพวกเขากำลังส่งมัน ด้วยการมาถึงของคำแนะนำลูกค้า ตัวแปร และข้อกำหนดของคีย์ การตอบสนองที่หลากหลายกำลังเริ่มต้นใหม่

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

วารีคืออะไร?

เรื่องราวของ Vary เริ่มต้นด้วยแนวคิดที่สวยงามว่าเว็บควรทำงานอย่างไร โดยหลักการแล้ว URL ไม่ได้หมายถึงหน้าเว็บ แต่เป็นแหล่งข้อมูลเชิงแนวคิด เช่น ใบแจ้งยอดจากธนาคารของคุณ ลองนึกภาพว่าคุณต้องการดูใบแจ้งยอดธนาคารของคุณ: คุณไปที่ bank.com และส่งคำขอ GET สำหรับ /statement จนถึงตอนนี้ดีมาก แต่คุณไม่ได้บอกว่าคุณต้องการคำสั่งในรูปแบบใด นี่คือเหตุผลที่เบราว์เซอร์ของคุณจะมีบางอย่างเช่น Accept: text/html ในคำขอของคุณ ในทางทฤษฎี อย่างน้อย นั่นหมายความว่าคุณสามารถพูดว่า Accept: text/csv แทน และรับทรัพยากรเดียวกันในรูปแบบอื่น

ภาพประกอบการสนทนาระหว่างผู้ใช้กับธนาคาร
(ดูรุ่นใหญ่)

เนื่องจากตอนนี้ URL เดียวกันสร้างการตอบสนองที่แตกต่างกันตามค่าของส่วนหัว Accept แคชใดๆ ที่เก็บการตอบกลับนี้จำเป็นต้องรู้ว่าส่วนหัวนั้นมีความสำคัญ เซิร์ฟเวอร์บอกเราว่าส่วนหัว Accept มีความสำคัญดังนี้:

 Vary: Accept

คุณสามารถอ่านได้ว่า "คำตอบนี้แตกต่างกันไปตามค่าของส่วนหัว Accept ของคำขอของคุณ"

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

ก่อนหน้านี้ฉันเคยเขียนเกี่ยวกับ Vary เกี่ยวกับเครือข่ายการส่งเนื้อหา (CDN) แคชตัวกลางเหล่านั้น (เช่น Fastly, CloudFront และ Akamai) ที่คุณสามารถวางไว้ระหว่างเซิร์ฟเวอร์และผู้ใช้ของคุณ เบราว์เซอร์ยังต้องเข้าใจและตอบสนองต่อกฎของ Vary และวิธีที่พวกเขาทำสิ่งนี้แตกต่างจากวิธีที่ CDN ปฏิบัติต่อ Vary ในโพสต์นี้ ฉันจะสำรวจโลกแห่งความแปรผันของแคชในเบราว์เซอร์

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

กรณีการใช้งานของวันนี้สำหรับการเปลี่ยนแปลงในเบราว์เซอร์

ดังที่เราเห็นก่อนหน้านี้ การใช้งาน Vary แบบดั้งเดิมคือดำเนินการเจรจาเนื้อหาโดยใช้ส่วนหัว Accept , Accept-Language และ Accept-Encoding และในอดีต สองรายการแรกล้มเหลวอย่างน่าสังเวช การ Accept-Encoding เพื่อส่งการตอบสนองที่บีบอัดด้วย Gzip หรือ Brotli ซึ่งได้รับการสนับสนุน ส่วนใหญ่จะทำงานได้ดีพอสมควร แต่เบราว์เซอร์ทั้งหมดรองรับ Gzip ในปัจจุบัน ดังนั้นจึงไม่น่าตื่นเต้นมากนัก

แล้วบางสถานการณ์เหล่านี้ล่ะ?

  • เราต้องการแสดงรูปภาพที่มีความกว้างเท่ากับหน้าจอของผู้ใช้ หากผู้ใช้ปรับขนาดเบราว์เซอร์ เราจะดาวน์โหลดภาพใหม่ (แตกต่างกันไปตามคำแนะนำของไคลเอ็นต์)
  • หากผู้ใช้ออกจากระบบ เราต้องการหลีกเลี่ยงการใช้เพจใดๆ ที่แคชไว้ในขณะที่พวกเขาเข้าสู่ระบบ (โดยใช้คุกกี้เป็น Key )
  • ผู้ใช้เบราว์เซอร์ที่สนับสนุนรูปแบบภาพ WebP ควรได้รับภาพ WebP มิฉะนั้น ควรได้รับ JPEG
  • เมื่อใช้เบราว์เซอร์บนหน้าจอที่มีความหนาแน่นสูง ผู้ใช้ควรได้ภาพ 2x หากพวกเขาย้ายหน้าต่างเบราว์เซอร์ไปยังหน้าจอความหนาแน่นมาตรฐานและรีเฟรช พวกเขาควรได้ภาพ 1x

แคชทุกทางลง

เบราว์เซอร์นี้ไม่เหมือนกับ edge cache ซึ่งทำหน้าที่เป็นแคชขนาดยักษ์ที่แชร์โดยผู้ใช้ทั้งหมด เบราว์เซอร์มีไว้สำหรับผู้ใช้เพียงรายเดียว แต่มีแคชที่แตกต่างกันมากมายสำหรับการใช้งานเฉพาะที่แตกต่างกัน:

ภาพประกอบของแคชในเบราว์เซอร์
(ดูรุ่นใหญ่)

สิ่งเหล่านี้บางส่วนค่อนข้างใหม่ และการทำความเข้าใจว่าแคชใดที่โหลดเนื้อหานั้นเป็นการคำนวณที่ซับซ้อนซึ่งไม่ได้รับการสนับสนุนอย่างดีจากเครื่องมือสำหรับนักพัฒนา นี่คือสิ่งที่แคชเหล่านี้ทำ:

  • แคชภาพ
    นี่คือแคชที่มีขอบเขตหน้าที่เก็บข้อมูลรูปภาพที่ถอดรหัส ตัวอย่างเช่น หากคุณรวมรูปภาพเดียวกันบนหน้าหลายครั้ง เบราว์เซอร์จะต้องดาวน์โหลดและถอดรหัสเพียงครั้งเดียว
  • โหลดแคชล่วงหน้า
    นอกจากนี้ยังมีการกำหนดขอบเขตหน้าเว็บและจัดเก็บทุกอย่างที่โหลดไว้ล่วงหน้าในส่วนหัวของ Link หรือแท็ก <link rel="preload"> แม้ว่าทรัพยากรนั้นปกติแล้วจะไม่สามารถแคชได้ เช่นเดียวกับแคชรูปภาพ แคชที่โหลดล่วงหน้าจะถูกทำลายเมื่อผู้ใช้ออกจากเพจ
  • แคชพนักงานบริการ API
    สิ่งนี้จัดเตรียมแคชแบ็คเอนด์พร้อมอินเทอร์เฟซที่ตั้งโปรแกรมได้ ดังนั้น จะไม่มีอะไรถูกเก็บไว้ที่นี่ เว้นแต่คุณจะใส่ไว้ที่นั่นผ่านโค้ด JavaScript ในพนักงานบริการโดยเฉพาะ นอกจากนี้ยังจะถูกตรวจสอบเฉพาะเมื่อคุณดำเนินการอย่างชัดแจ้งในตัวจัดการการ fetch ของพนักงานบริการ แคชของเจ้าหน้าที่บริการมีการกำหนดขอบเขตเริ่มต้น และแม้ว่าจะไม่รับประกันว่าจะคงอยู่ถาวร แต่ก็มีความคงอยู่มากกว่าแคช HTTP ของเบราว์เซอร์
  • แคช HTTP
    นี่คือแคชหลักที่ผู้คนคุ้นเคยมากที่สุด เป็นแคชเพียงแคชเดียวที่ให้ความสนใจกับส่วนหัวของแคชระดับ HTTP เช่น Cache-Control และรวมสิ่งเหล่านี้เข้ากับกฎฮิวริสติกของเบราว์เซอร์เองเพื่อพิจารณาว่าจะแคชบางสิ่งหรือไม่และนานแค่ไหน มีขอบเขตกว้างที่สุด แบ่งปันโดยเว็บไซต์ทั้งหมด ดังนั้น หากเว็บไซต์ที่ไม่เกี่ยวข้องสองแห่งโหลดเนื้อหาเดียวกัน (เช่น Google Analytics) เว็บไซต์เหล่านั้นอาจใช้แคชเดียวกันร่วมกัน
  • แคชพุช HTTP/2 (หรือ “แคชพุช H2”)
    สิ่งนี้อยู่กับการเชื่อมต่อ และเก็บวัตถุที่ถูกผลักจากเซิร์ฟเวอร์ แต่ยังไม่ได้รับการร้องขอจากหน้าใด ๆ ที่ใช้การเชื่อมต่อ มีการกำหนดขอบเขตไปยังหน้าต่างๆ โดยใช้การเชื่อมต่อเฉพาะ ซึ่งโดยพื้นฐานแล้วจะเหมือนกับการกำหนดขอบเขตไปยังต้นทางเดียว แต่จะถูกทำลายเมื่อการเชื่อมต่อปิดลง

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

ลำดับที่คำขอตรวจสอบแคชเหล่านี้ก่อนที่จะเข้าสู่เครือข่ายนั้นมีความสำคัญ เนื่องจากคำขอบางอย่างอาจดึงแคชจากเลเยอร์ภายนอกของแคชเข้าสู่ภายใน ตัวอย่างเช่น หากเซิร์ฟเวอร์ HTTP/2 ของคุณพุชสไตล์ชีตพร้อมกับหน้าที่ต้องการ และหน้านั้นโหลดสไตล์ชีตไว้ล่วงหน้าด้วยแท็ก <link rel="preload"> สไตล์ชีตจะแตะสามส่วน แคชในเบราว์เซอร์ ขั้นแรก มันจะนั่งในแคชพุช H2 เพื่อรอการร้องขอ เมื่อเบราว์เซอร์แสดงผลหน้าเว็บและไปที่แท็ก preload เบราว์เซอร์จะดึงสไตล์ชีตออกจากแคชแบบพุช ผ่านแคช HTTP (ซึ่งอาจจัดเก็บไว้ ขึ้นอยู่กับส่วนหัวของ Cache-Control ของสไตล์ชีต) และจะบันทึก มันอยู่ในแคชโหลดล่วงหน้า

HTTP/2 PUSH ไหลผ่านแคชของเบราว์เซอร์
(ดูรุ่นใหญ่)

ขอแนะนำ Vary As A Validator

โอเค จะเกิดอะไรขึ้นเมื่อเรานำสถานการณ์นี้และเพิ่ม Vary ลงในมิกซ์

ไม่เหมือนกับแคชตัวกลาง (เช่น CDN) เบราว์เซอร์มัก ไม่ใช้ความสามารถในการจัดเก็บรูปแบบต่างๆ ต่อ URL เหตุผลก็คือสิ่งที่เรามักใช้ Vary สำหรับ (ส่วนใหญ่เป็น Accept-Encoding และ Accept-Language ) จะไม่เปลี่ยนแปลงบ่อยในบริบทของผู้ใช้คนเดียว Accept-Encoding อาจ (แต่อาจไม่) เปลี่ยนแปลงเมื่ออัปเกรดเบราว์เซอร์ และ Accept-Language มักจะเปลี่ยนหากคุณแก้ไขการตั้งค่าภาษาของระบบปฏิบัติการของคุณเท่านั้น นอกจากนี้ยังง่ายกว่ามากในการปรับใช้ Vary ด้วยวิธีนี้ แม้ว่าผู้เขียนข้อมูลจำเพาะบางคนเชื่อว่านี่เป็นข้อผิดพลาด

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

การประนีประนอมคือการปฏิบัติต่อ Vary ในฐานะผู้ตรวจสอบ ไม่ใช่กุญแจ เบราว์เซอร์คำนวณคีย์แคชด้วยวิธีปกติ (โดยพื้นฐานแล้ว โดยใช้ URL) จากนั้นหากพวกเขาทำคะแนน พวกเขาจะตรวจสอบว่าคำขอเป็นไปตามกฎ Vary ใดๆ ที่รวมเข้ากับการตอบสนองที่แคชไว้ หากไม่เป็นเช่นนั้น เบราว์เซอร์จะถือว่าคำขอนั้นพลาดในแคช และจะย้ายไปยังแคชชั้นถัดไปหรือออกไปยังเครือข่าย เมื่อได้รับการตอบกลับใหม่ มันจะเขียนทับเวอร์ชันที่แคชไว้ แม้ว่าในทางเทคนิคแล้วจะเป็นรูปแบบที่แตกต่างออกไป

การแสดงพฤติกรรมที่แตกต่าง

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

มาดูแคชแต่ละประเภทกันและว่า Vary ควรทำงานอย่างไร และมันทำงานเช่นนั้นจริงหรือไม่ สำหรับการทดสอบแต่ละครั้ง ฉันแสดงที่นี่ว่าเราควรคาดหวังว่าจะได้เห็นผลลัพธ์จากแคช (“HIT” กับ “MISS”) และสิ่งที่เกิดขึ้นจริง

พรีโหลด

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

ผลการทดสอบ link rel=preload ใน Google Chrome
(ดูรุ่นใหญ่)

API แคชพนักงานบริการ

Chrome และ Firefox สนับสนุนผู้ปฏิบัติงานบริการ และในการพัฒนาข้อกำหนดของผู้ปฏิบัติงานบริการ ผู้เขียนต้องการแก้ไขสิ่งที่พวกเขาเห็นว่าเป็นการใช้งานที่ใช้งานไม่ได้ในเบราว์เซอร์ เพื่อให้ Vary ในเบราว์เซอร์ทำงานเหมือน CDN มากขึ้น ซึ่งหมายความว่าในขณะที่เบราว์เซอร์ควรจัดเก็บรูปแบบเดียวในแคช HTTP แต่ควรเก็บรูปแบบที่หลากหลายใน Cache API Firefox (54) ทำสิ่งนี้อย่างถูกต้อง ในขณะที่ Chrome ใช้ตรรกะ vary-as-validator เดียวกันกับที่ใช้สำหรับแคช HTTP (กำลังติดตามจุดบกพร่อง)

ผลการทดสอบแคชพนักงานบริการใน Google Chrome
(ดูรุ่นใหญ่)

แคช HTTP

แคช HTTP หลักควรสังเกต Vary และทำอย่างสม่ำเสมอ (ในฐานะเครื่องมือตรวจสอบความถูกต้อง) ในทุกเบราว์เซอร์ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ โปรดดูโพสต์ของ Mark Nottingham เรื่อง “State of Browser Caching, Revisited”

HTTP/2 พุชแคช

ควรสังเกตความ Vary แต่ในทางปฏิบัติไม่มีเบราว์เซอร์ใดเคารพมัน และเบราว์เซอร์จะจับคู่และใช้การตอบกลับแบบพุชอย่างมีความสุขกับคำขอที่มีค่าสุ่มในส่วนหัวที่การตอบสนองแตกต่างกันไป

ผลการทดสอบ H2 push cache ใน Google Chrome
(ดูรุ่นใหญ่)

ริ้วรอย “304 (ไม่ดัดแปลง)”

สถานะการตอบสนอง HTTP “304 (ไม่ได้แก้ไข)” นั้นน่าทึ่งมาก "ผู้นำที่รัก" ของเรา Artur Bergman ชี้ให้เห็นอัญมณีนี้ในข้อกำหนดการแคช HTTP (เน้น):

เซิร์ฟเวอร์ที่สร้างการตอบสนอง 304 จะต้อง สร้างฟิลด์ส่วนหัวใดๆ ต่อไปนี้ที่จะถูกส่งในการตอบกลับ 200 (OK) ต่อคำขอเดียวกัน: Cache-Control , Content-Location , Date , ETag , Expires และ Vary

เหตุใดการตอบสนอง 304 จึงส่งคืนส่วนหัว Vary พล็อตจะเข้มข้นขึ้นเมื่อคุณอ่านเกี่ยวกับสิ่งที่คุณควรทำเมื่อได้รับการตอบกลับ 304 ที่มีส่วนหัวเหล่านั้น:

หากเลือกการตอบสนองที่เก็บไว้สำหรับการอัปเดต แคช จะต้อง \[…] ใช้ฟิลด์ส่วนหัวอื่นที่มีให้ในการตอบสนอง 304 (ไม่ได้แก้ไข) เพื่อแทนที่อินสแตนซ์ทั้งหมดของฟิลด์ส่วนหัวที่เกี่ยวข้องในการตอบกลับที่เก็บไว้

รออะไร? ดังนั้น หากส่วนหัว Vary ของ 304 แตกต่างจากในวัตถุแคชที่มีอยู่ เราควรอัปเดตวัตถุที่แคชหรือไม่ แต่นั่นอาจหมายความว่ามันไม่ตรงกับคำขอของเราอีกต่อไป!

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

(หมายเหตุด้านข้าง: Fastly เราไม่เคารพข้อกำหนดเฉพาะนี้ ดังนั้น หากเราได้รับ 304 จากเซิร์ฟเวอร์ต้นทางของคุณ เราจะใช้วัตถุแคชต่อไปโดยไม่มีการแก้ไข นอกเหนือจากการรีเซ็ต TTL)

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

คำแนะนำลูกค้า

คุณลักษณะคำแนะนำลูกค้าของ Google เป็นหนึ่งในสิ่งใหม่ที่สำคัญที่สุดที่จะเกิดขึ้นกับ Vary ในเบราว์เซอร์ในระยะเวลาอันยาวนาน แตกต่างจาก Accept-Encoding และ Accept-Language ตรงที่ Client Hints อธิบายค่าที่อาจเปลี่ยนแปลงอย่างสม่ำเสมอเมื่อผู้ใช้ย้ายไปรอบๆ เว็บไซต์ของคุณ โดยเฉพาะสิ่งต่อไปนี้:

  • DPR
    อัตราส่วนพิกเซลของอุปกรณ์ ความหนาแน่นของพิกเซลของหน้าจอ (อาจแตกต่างกันไปหากผู้ใช้มีหลายหน้าจอ)
  • Save-Data
    ไม่ว่าผู้ใช้จะเปิดใช้งานโหมดประหยัดข้อมูลหรือไม่
  • Viewport-Width
    ความกว้างพิกเซลของวิวพอร์ตปัจจุบัน
  • Width
    ความกว้างของทรัพยากรที่ต้องการในหน่วยพิกเซลจริง

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

ข้อเสนอส่วนหัวที่สำคัญ

คำแนะนำลูกค้าและส่วนหัวอื่นๆ ที่ละเอียดมากยืมตัวมาสู่ข้อเสนอที่ Mark กำลังดำเนินการอยู่ ซึ่งมีชื่อว่า Key ลองดูตัวอย่างสองสามตัวอย่าง:

 Key: Viewport-Width;div=50

สิ่งนี้บอกว่าการตอบสนองแตกต่างกันไปตามค่าของส่วนหัวคำขอ Viewport-Width แต่ปัดเศษลงให้ใกล้เคียงที่สุดที่ 50 พิกเซล!

 Key: cookie;param=sessionAuth;param=flags

การเพิ่มส่วนหัวนี้ในการตอบกลับหมายความว่าเรากำลังเปลี่ยนแปลงคุกกี้เฉพาะสองรายการ: sessionAuth และ flags หากไม่มีการเปลี่ยนแปลง เราสามารถนำคำตอบนี้กลับมาใช้ใหม่สำหรับคำขอในอนาคต

ดังนั้น ความแตกต่างที่สำคัญระหว่าง Key และ Vary คือ:

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

ในขณะที่เขียน ไม่มีเบราว์เซอร์หรือ CDN ใดรองรับ Key แม้ว่าใน CDN บางรายการ คุณอาจได้รับผลเช่นเดียวกันโดยแยกส่วนหัวขาเข้าออกเป็นส่วนหัวส่วนตัวหลายรายการและแตกต่างกัน (ดูโพสต์ของเรา “การได้รับประโยชน์สูงสุดจากความแตกต่างด้วย อย่างรวดเร็ว”) ดังนั้นเบราว์เซอร์จึงเป็นส่วนหลักที่ Key สามารถสร้างผลกระทบได้

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

ข้อเสนอรูปแบบต่างๆ

Key เป็นกลไกทั่วไปที่ดี แต่ส่วนหัวบางตัวมีกฎเกณฑ์ที่ซับซ้อนกว่าสำหรับค่าของพวกมัน และการทำความเข้าใจความหมายของค่าเหล่านั้นสามารถช่วยเราค้นหาวิธีอัตโนมัติในการลดความแปรผันของแคช ตัวอย่างเช่น สมมติว่าคำขอสองรายการมาพร้อมกับค่า Accept-Language แตกต่างกัน ได้แก่ en-gb และ en-us แต่ถึงแม้ว่าเว็บไซต์ของคุณจะรองรับรูปแบบภาษาต่างๆ แต่คุณก็มี "ภาษาอังกฤษ" เพียงคำเดียวเท่านั้น หากเราตอบคำขอภาษาอังกฤษแบบสหรัฐอเมริกาและการตอบสนองนั้นถูกแคชไว้บน CDN จะไม่สามารถนำกลับมาใช้ใหม่สำหรับคำขอภาษาอังกฤษแบบอังกฤษได้ เนื่องจากค่า Accept-Language จะแตกต่างกันและแคชไม่ฉลาดพอที่จะรู้ได้ดีขึ้น .

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

ขณะนี้ Variants เป็นเวอร์ชันร่างแรกๆ และเนื่องจากได้รับการออกแบบมาเพื่อช่วยใน Accept-Encoding และ Accept-Language ประโยชน์ของมันจึงค่อนข้างจำกัดเฉพาะแคชที่แชร์ เช่น CDN แทนที่จะเป็นแคชของเบราว์เซอร์ แต่มันจับคู่กับ Key ได้อย่างดีและทำให้ภาพสมบูรณ์เพื่อการควบคุมรูปแบบแคชที่ดียิ่งขึ้น

บทสรุป

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

  • เบราว์เซอร์ส่วนใหญ่ถือว่า Vary เป็นตัวตรวจสอบความถูกต้อง หากคุณต้องการแคชรูปแบบที่แยกจากกันหลายแบบ ให้ค้นหาวิธีใช้ URL อื่นแทน
  • เบราว์เซอร์จะละเว้น Vary สำหรับทรัพยากรที่พุชโดยใช้การพุชของเซิร์ฟเวอร์ HTTP/2 ดังนั้นอย่าเปลี่ยนสิ่งที่คุณพุช
  • เบราว์เซอร์มีแคชมากมาย และทำงานในรูปแบบต่างๆ คุณควรพยายามทำความเข้าใจว่าการตัดสินใจแคชของคุณส่งผลต่อประสิทธิภาพการทำงานแต่ละรายการอย่างไร โดยเฉพาะอย่างยิ่งในบริบทของ Vary
  • Vary ไม่ได้มีประโยชน์เท่าที่ควร และ Key ที่จับคู่กับคำแนะนำลูกค้ากำลังเริ่มที่จะเปลี่ยนแปลงสิ่งนั้น ติดตามพร้อมกับการสนับสนุนเบราว์เซอร์เพื่อดูว่าคุณสามารถเริ่มใช้งานได้เมื่อใด

ออกไปและเป็นตัวแปร