ข้อมูลเบื้องต้นเกี่ยวกับ HTTP/2

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

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

HTTP/2 ไม่ได้แก้ไขอรรถศาสตร์ของแอปพลิเคชันของ HTTP แต่อย่างใด แนวคิดหลักทั้งหมด เช่น เมธอด HTTP, รหัสสถานะ, URI และช่องส่วนหัวจะยังคงอยู่ แต่ HTTP/2 จะแก้ไขวิธีจัดรูปแบบ (เฟรม) และการรับส่งข้อมูลระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์แทน ซึ่งทั้งคู่จะจัดการกระบวนการทั้งหมดและซ่อนความซับซ้อนทั้งหมดจากแอปพลิเคชันของเราภายในเลเยอร์เฟรมใหม่ ซึ่งส่งผลให้สามารถนำส่งแอปพลิเคชันที่มีอยู่ทั้งหมดได้โดยไม่ต้องแก้ไข

เหตุใดจึงไม่ใช้ HTTP/1.2

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

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

ประวัติโดยย่อของ SPDY และ HTTP/2

SPDY เป็นโปรโตคอลทดลองที่พัฒนาขึ้นที่ Google และได้ประกาศเมื่อกลางปี 2009 ซึ่งมีเป้าหมายหลักเพื่อพยายามลดเวลาในการตอบสนองของการโหลดหน้าเว็บโดยจัดการกับข้อจำกัดด้านประสิทธิภาพที่เป็นที่รู้จักของ HTTP/1.1 โดยเฉพาะอย่างยิ่ง ได้มีการตั้งเป้าหมายโครงการไว้ดังนี้

  • กำหนดเป้าหมายเพื่อลดเวลาในการโหลดหน้าเว็บ (PLT) ลง 50%
  • หลีกเลี่ยงความจำเป็นที่ผู้เขียนเว็บไซต์จะต้องเปลี่ยนแปลงเนื้อหา
  • ลดความซับซ้อนในการทำให้ใช้งานได้และหลีกเลี่ยงการเปลี่ยนแปลงในโครงสร้างพื้นฐานของเครือข่าย
  • พัฒนาโปรโตคอลใหม่นี้ร่วมกับชุมชนโอเพนซอร์ส
  • รวบรวมข้อมูลประสิทธิภาพจริงเพื่อ (in) ตรวจสอบความถูกต้องของโปรโตคอลทดลอง

หลังจากการประกาศครั้งแรกไม่นาน Mike Belshe และ Roberto Peon วิศวกรซอฟต์แวร์ของ Google ได้แชร์ผลลัพธ์แรก เอกสารประกอบ และซอร์สโค้ดสำหรับการใช้งานโปรโตคอล SPDY ใหม่เวอร์ชันทดลอง:

ตอนนี้เราได้ทดสอบ SPDY ในสภาพห้องทดลองเท่านั้น ผลลัพธ์เบื้องต้นที่น่าพอใจมากคือ เมื่อเราดาวน์โหลดเว็บไซต์ 25 อันดับแรกผ่านการเชื่อมต่อเครือข่ายในบ้านจำลอง เราเห็นประสิทธิภาพที่ดีขึ้นอย่างเห็นได้ชัด โดยหน้าเว็บจะโหลดเร็วขึ้นถึง 55% (บล็อก Chromium)

มองไปข้างหน้าสู่ปี 2012 และโปรโตคอลทดลองใหม่ได้รับการรองรับใน Chrome, Firefox และ Opera และเว็บไซต์จำนวนมาก (เช่น Google, Twitter, Facebook) และเว็บไซต์ขนาดเล็กก็ใช้งาน SPDY ภายในโครงสร้างพื้นฐานกันเป็นจำนวนมาก ผลที่ได้ก็คือ SPDY เดินหน้าสู่การเป็นมาตรฐานอันดีจริง ผ่านการใช้อุตสาหกรรมที่กำลังเติบโต

เมื่อสังเกตแนวโน้มนี้ คณะทำงาน HTTP (HTTP-WG) ก็ได้เริ่มต้นความพยายามใหม่ที่จะนำบทเรียนที่เรียนรู้จาก SPDY มาปรับปรุงและพัฒนาให้ดีขึ้น ตลอดจนมอบมาตรฐาน "HTTP/2" อย่างเป็นทางการ มีการร่างสัญญาบัตรใหม่ มีการเปิดใจเพื่อขอข้อเสนอ HTTP/2 และหลังจากมีการพูดคุยกันหลายครั้งภายในกลุ่มทำงาน ก็มีการนำข้อกำหนด SPDY มาใช้เป็นจุดเริ่มต้นสำหรับโปรโตคอล HTTP/2 ใหม่

ในช่วง 2-3 ปีต่อมา SPDY และ HTTP/2 ยังคงพัฒนาอย่างต่อเนื่อง โดย SPDY จะทำหน้าที่เป็นสาขาทดลองที่ใช้ทดสอบฟีเจอร์และข้อเสนอใหม่ๆ สำหรับมาตรฐาน HTTP/2 สิ่งที่สวยงามบนกระดาษอาจไม่นำมาใช้จริงและในทางกลับกัน และ SPDY ก็ได้เสนอแนวทางการทดสอบและประเมินแต่ละข้อเสนอก่อนที่จะรวมไว้ในมาตรฐาน HTTP/2 ในท้ายที่สุด กระบวนการนี้ก็กินเวลาถึง 3 ปี และส่งผลให้มีการดราฟท์ตัวกลางกว่า 10 ฉบับ ดังนี้

  • มีนาคม 2012: การเรียกข้อเสนอสำหรับ HTTP/2
  • พฤศจิกายน 2012: ฉบับร่างแรกของ HTTP/2 (อิงตาม SPDY)
  • สิงหาคม 2014: เผยแพร่ HTTP/2Draft-17 และ HPACKDraft-12
  • สิงหาคม 2014: คณะทำงานสายล่าสุดสำหรับ HTTP/2
  • กุมภาพันธ์ 2015: IESG อนุมัติ HTTP/2 และร่าง HPACK
  • พฤษภาคม 2015: เผยแพร่ RFC 7540 (HTTP/2) และ RFC 7541 (HPACK)

ในช่วงต้นปี 2015 IESG ได้ตรวจสอบและอนุมัติมาตรฐาน HTTP/2 ใหม่สำหรับการเผยแพร่ หลังจากนั้นไม่นาน ทีม Google Chrome ก็ประกาศกำหนดการ ในการเลิกใช้งานส่วนขยาย SPDY และ NPN สำหรับ TLS ดังนี้

การเปลี่ยนแปลงหลักของ HTTP/2 จาก HTTP/1.1 เน้นที่ประสิทธิภาพที่ดีขึ้น ฟีเจอร์สำคัญๆ บางอย่าง เช่น การมัลติเพล็กซ์ การบีบอัดส่วนหัว การจัดลำดับความสำคัญ และการเจรจาโปรโตคอลพัฒนามาจากงานที่ทำก่อนหน้านี้แบบเปิด แต่ไม่ได้เป็นโปรโตคอลมาตรฐานชื่อ SPDY Chrome รองรับ SPDY ตั้งแต่ Chrome 6 แต่เนื่องจากประโยชน์ส่วนใหญ่มีอยู่ใน HTTP/2 แล้ว ตอนนี้ก็ถึงเวลาบอกลา เราวางแผนที่จะยกเลิกการสนับสนุน SPDY ในช่วงต้นปี 2016 และจะยกเลิกการรองรับส่วนขยาย TLS ชื่อ NPN เพื่อเปลี่ยนไปใช้ ALPN ใน Chrome พร้อมกัน เราขอแนะนำให้นักพัฒนาเซิร์ฟเวอร์เปลี่ยนไปใช้ HTTP/2 และ ALPN

เรายินดีที่ได้มีส่วนร่วมในกระบวนการของมาตรฐานแบบเปิดซึ่งนำไปสู่ HTTP/2 และหวังว่าจะได้เห็นการนำไปใช้ในวงกว้างเนื่องจากการมีส่วนร่วมในแวดวงอุตสาหกรรมเกี่ยวกับมาตรฐานและการใช้งาน (บล็อก Chromium)

การพัฒนาร่วมกันของ SPDY และ HTTP/2 ทำให้นักพัฒนาเซิร์ฟเวอร์ เบราว์เซอร์ และเว็บไซต์ ได้รับประสบการณ์การใช้งานจริงกับโปรโตคอลใหม่ที่กำลังพัฒนา ด้วยเหตุนี้ มาตรฐาน HTTP/2 จึงเป็นมาตรฐานที่ดีที่สุดและได้รับการทดสอบอย่างครอบคลุมมากที่สุดตั้งแต่เริ่มต้น ในขณะที่ HTTP/2 ได้รับการอนุมัติจาก IESG ก็มีการทดสอบการใช้งานไคลเอ็นต์และเซิร์ฟเวอร์ที่พร้อมสำหรับเวอร์ชันที่ใช้งานจริงอย่างละเอียดหลายสิบรายการ ในความเป็นจริงหลังจากที่โปรโตคอลสุดท้ายได้รับอนุมัติแล้วเพียงไม่กี่สัปดาห์ ผู้ใช้หลายคนก็ได้รับประโยชน์จากโปรโตคอลนี้แล้วเนื่องจากเบราว์เซอร์ยอดนิยมหลายตัว (และเว็บไซต์จำนวนมาก) ใช้การสนับสนุน HTTP/2 เต็มรูปแบบ

เป้าหมายด้านการออกแบบและทางเทคนิค

โปรโตคอล HTTP เวอร์ชันก่อนหน้าได้รับการออกแบบมาโดยตั้งใจให้ใช้งานง่าย โดย HTTP/0.9 เป็นโปรโตคอลบรรทัดเดียวเพื่อเริ่มต้นระบบเวิลด์ไวด์เว็บ, HTTP/1.0 บันทึกส่วนขยายยอดนิยมของ HTTP/0.9 ไว้ในมาตรฐานข้อมูล, HTTP/1.1 มีมาตรฐาน IETF อย่างเป็นทางการ โปรดดูประวัติโดยย่อของ HTTP ด้วยเหตุนี้ HTTP/0.9-1.x จึงนำเสนอสิ่งที่ต้องการอย่างถูกต้อง นั่นคือ HTTP เป็นโปรโตคอลแอปพลิเคชันหนึ่งที่ใช้กันอย่างแพร่หลายในอินเทอร์เน็ต

ความเรียบง่ายในการใช้งานยังทำให้เกิดต้นทุนสำหรับประสิทธิภาพของแอปพลิเคชันด้วย ไคลเอ็นต์ HTTP/1.x ต้องใช้การเชื่อมต่อหลายรายการเพื่อให้ได้การเกิดขึ้นพร้อมกันและลดเวลาในการตอบสนอง HTTP/1.x ไม่บีบอัดคำขอและส่วนหัวการตอบกลับ ทำให้เกิดการจราจรของข้อมูลในเครือข่ายที่ไม่จำเป็น ขณะที่ HTTP/1.x ไม่อนุญาตให้จัดลำดับความสำคัญของทรัพยากรที่มีประสิทธิภาพ ทำให้ใช้การเชื่อมต่อ TCP ที่สำคัญอยู่ไม่ดี และอื่นๆ

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

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

โปรโตคอลที่ได้เหมาะกับเครือข่ายมากกว่าเนื่องจากมีการเชื่อมต่อ TCP น้อยกว่าเมื่อเทียบกับ HTTP/1.x ซึ่งหมายความว่าขั้นตอนอื่นๆ จะมีการแข่งขันน้อยลง รวมถึงการเชื่อมต่อที่มีระยะเวลานานขึ้น ซึ่งทำให้ใช้ความจุเครือข่ายที่มีได้ดียิ่งขึ้น สุดท้าย HTTP/2 ยังทำให้การประมวลผลข้อความมีประสิทธิภาพมากขึ้นโดยใช้การจัดกรอบข้อความแบบไบนารี (Hypertext Transfer Protocol เวอร์ชัน 2 ฉบับร่าง 17)

โปรดทราบว่า HTTP/2 จะขยายต่อมาตรฐาน HTTP ก่อนหน้า ไม่ใช่การแทนที่ อรรถศาสตร์ของแอปพลิเคชันของ HTTP จะเหมือนกันและไม่มีการเปลี่ยนแปลงใดๆ ในฟังก์ชันการทำงานที่เสนอหรือแนวคิดหลัก เช่น เมธอด HTTP, รหัสสถานะ, URI และช่องส่วนหัว การเปลี่ยนแปลงเหล่านี้อยู่นอกขอบเขตการทำงานของ HTTP/2 อย่างชัดเจน อย่างไรก็ตาม แม้ว่า API ระดับสูงจะยังคงเหมือนเดิม แต่คุณควรทำความเข้าใจว่าการเปลี่ยนแปลงในระดับต่ำนั้นแก้ไขข้อจำกัดด้านประสิทธิภาพของโปรโตคอลก่อนหน้าอย่างไร เรามาดูวิดีโอสั้นๆ ของเลเยอร์เฟรมไบนารี และฟีเจอร์ต่างๆ กัน

เลเยอร์การจัดเฟรมไบนารี

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

เลเยอร์การจัดเฟรมไบนารี HTTP/2

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

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

สตรีม ข้อความ และเฟรม

การเปิดตัวกลไกการจัดเฟรมแบบไบนารีใหม่จะเปลี่ยนแปลงวิธีการแลกเปลี่ยนข้อมูลระหว่างไคลเอ็นต์กับเซิร์ฟเวอร์ ในการอธิบายกระบวนการนี้ คุณต้องทำความคุ้นเคยกับคำศัพท์ HTTP/2 ดังนี้

  • สตรีม: การไหลแบบ 2 ทิศทางของไบต์ภายในการเชื่อมต่อที่มีอยู่แล้ว ซึ่งอาจมีข้อความอย่างน้อย 1 รายการ
  • ข้อความ: ลำดับเฟรมที่สมบูรณ์ซึ่งแมปกับคำขอเชิงตรรกะหรือข้อความตอบกลับ
  • เฟรม: หน่วยการสื่อสารที่เล็กที่สุดใน HTTP/2 โดยแต่ละหน่วยมีส่วนหัวของเฟรม ซึ่งอย่างน้อยที่สุดจะระบุสตรีมที่มีเฟรมอยู่

ความเกี่ยวข้องของข้อกำหนดเหล่านี้สามารถสรุปได้ดังนี้

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

สตรีม HTTP/2 ข้อความ และเฟรม

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

การส่งคำขอและคำตอบแบบมัลติเพล็กซ์

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

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

คำขอ HTTP/2 และการทำมัลติเพล็กซ์การตอบสนองภายในการเชื่อมต่อที่แชร์

สแนปชอตจะบันทึกสตรีมหลายรายการในช่วงแสดงโฆษณาภายในการเชื่อมต่อเดียวกัน ไคลเอ็นต์กำลังส่งเฟรม DATA (สตรีม 5) ไปยังเซิร์ฟเวอร์ ขณะที่เซิร์ฟเวอร์กำลังส่งลำดับเฟรมแบบแทรกสลับไปยังไคลเอ็นต์สำหรับสตรีม 1 และ 3 จึงทำให้มีการสตรีมพร้อมกัน 3 สตรีมเกิดขึ้นพร้อมกัน

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

  • แทรกคำขอหลายรายการพร้อมกันโดยไม่บล็อกคำขอใด
  • แทรกคำตอบหลายรายการพร้อมกันโดยไม่บล็อกคำตอบใด
  • ใช้การเชื่อมต่อเดียวเพื่อส่งคําขอและคําตอบหลายรายการพร้อมกัน
  • นำการแก้ปัญหาชั่วคราวของ HTTP/1.x ที่ไม่จำเป็นออก (ดูการเพิ่มประสิทธิภาพสำหรับ HTTP/1.x เช่น ไฟล์แบบต่อกัน สไปรท์รูปภาพ และชาร์ดดิ้งโดเมน)
  • ลดเวลาในการโหลดหน้าเว็บโดยขจัดเวลาในการตอบสนองที่ไม่จำเป็นและปรับปรุงการใช้ความจุเครือข่ายที่มีอยู่
  • และอีกมากมาย...

เลเยอร์เฟรมแบบไบนารีใหม่ใน HTTP/2 จะช่วยแก้ปัญหาการบล็อกบรรทัดแรกที่พบใน HTTP/1.x และลดความจำเป็นในการเชื่อมต่อหลายรายการเพื่อเปิดใช้การประมวลผลแบบคู่ขนาน ตลอดจนการส่งคำขอและการตอบกลับ จึงทำให้แอปพลิเคชันของเราติดตั้งได้เร็วขึ้น ง่ายขึ้น และถูกลง

การจัดลำดับความสำคัญของสตรีม

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

  • แต่ละสตรีมอาจได้รับน้ำหนักเป็นเลขจำนวนเต็มระหว่าง 1 ถึง 256
  • แต่ละสตรีมอาจได้รับการขึ้นต่อกันกับสตรีมอื่นอย่างชัดเจน

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

ทรัพยากร Dependency และน้ำหนักของสตรีม HTTP/2

ระบบจะประกาศทรัพยากร Dependency ของสตรีมภายใน HTTP/2 โดยอ้างอิงตัวระบุที่ไม่ซ้ำกันของสตรีมอื่นเป็นสตรีมระดับบนสุด หากไม่ระบุตัวระบุ จะถือว่าสตรีมดังกล่าวขึ้นอยู่กับ "สตรีมระดับรูท" การประกาศการขึ้นต่อกันของสตรีมเป็นการระบุว่า หากเป็นไปได้ ควรจัดสรรทรัพยากรให้ก่อนทรัพยากร Dependency ของสตรีมดังกล่าว กล่าวคือ "โปรดประมวลผลและส่งคำตอบ D ก่อนคำตอบ C"

สตรีมที่มีเครือข่ายระดับบนสุดเดียวกัน (กล่าวคือ สตรีมระดับเดียวกัน) ควรได้รับการจัดสรรทรัพยากรตามสัดส่วนของน้ำหนัก ตัวอย่างเช่น หากสตรีม A มีน้ำหนักเท่ากับ 12 และสตรีมข้างเคียง B หนึ่งมีน้ำหนักเท่ากับ 4 คุณจะต้องพิจารณาสัดส่วนของทรัพยากรที่สตรีมแต่ละรายการเหล่านี้ควรได้รับ

  1. รวมน้ำหนักทั้งหมด: 4 + 12 = 16
  2. หารน้ำหนักของสตรีมแต่ละรายการด้วยน้ำหนักรวม: A = 12/16, B = 4/16

ดังนั้นสตรีม A จึงควรได้รับ 3 ใน 4 ส่วนสตรีม B ควรได้รับทรัพยากรที่พร้อมใช้งาน 1 ใน 4 ส่วนสตรีม B ควรได้รับ 1 ใน 3 ของทรัพยากรที่จัดสรรไว้สำหรับสตรีม A มาดูตัวอย่างจริงเพิ่มเติม ในรูปภาพด้านบนกัน จากซ้ายไปขวา:

  1. ทั้งสตรีม A และ B ไม่ได้ระบุทรัพยากร Dependency ระดับบนสุดและเชื่อกันว่าอิงตาม "สตรีมราก" โดยนัย โดย A มีน้ำหนักเท่ากับ 12 และ B มีน้ำหนักเท่ากับ 4 ดังนั้น เมื่ออิงตามน้ำหนักตามสัดส่วน สตรีม B ควรได้รับ 1 ใน 3 ของทรัพยากรที่จัดสรรไว้สำหรับสตรีม A
  2. สตรีม D ขึ้นอยู่กับสตรีมราก ส่วน C อาศัย D ดังนั้น D จึงควรได้รับการจัดสรร ทรัพยากรทั้งหมดก่อน C น้ำหนักไม่เป็นผลตามมา เพราะทรัพยากร Dependency ของ C บอกถึงความต้องการที่มากกว่า
  3. สตรีม D ควรได้รับการจัดสรรทรัพยากรทั้งหมดก่อน C ส่วน C ควรได้รับการจัดสรรทรัพยากรทั้งหมดก่อน A และ B ส่วนสตรีม B ควรได้รับ 1 ใน 3 ของทรัพยากรที่จัดสรรไว้สำหรับสตรีม A
  4. สตรีม D ควรได้รับการจัดสรรทรัพยากรก่อน E และ C โดยสมบูรณ์ ส่วน E และ C ควรได้รับการจัดสรรอย่างเท่าเทียมก่อน A และ B ส่วน A และ B ควรได้รับการจัดสรรตามสัดส่วนโดยอิงตามน้ำหนักของสตรีม

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

การเชื่อมต่อ 1 รายการต่อต้นทาง

เมื่อใช้กลไกการจัดเฟรมแบบไบนารีใหม่ HTTP/2 ไม่ต้องใช้การเชื่อมต่อ TCP หลายรายการกับสตรีม Multiplex พร้อมกันอีกต่อไป โดยแต่ละสตรีมจะแยกออกเป็นหลายเฟรม ซึ่งจะแทรกและจัดลำดับความสำคัญได้ ดังนั้นการเชื่อมต่อ HTTP/2 ทั้งหมดจะเป็นแบบถาวรและต้องใช้การเชื่อมต่อเพียง 1 รายการต่อต้นทางเท่านั้น ซึ่งให้ประโยชน์ด้านประสิทธิภาพหลายประการ

สำหรับทั้ง SPDY และ HTTP/2 ฟีเจอร์สำคัญคือการมัลติเพล็กซ์แบบอิสระในช่องทางที่ควบคุมความคับคั่งเพียงช่องทางเดียว ผมทึ่งมากที่ฟีเจอร์นี้ สำคัญและได้ผลดีขนาดไหน เมตริกที่ดีมากอย่างหนึ่งคือเส้นแบ่งของการเชื่อมต่อที่สร้างขึ้นที่มีธุรกรรม HTTP เพียงรายการเดียว (ทำให้ธุรกรรมนั้นแบกรับค่าใช้จ่ายทั้งหมด) สำหรับ HTTP/1 การเชื่อมต่อที่ใช้งานอยู่ 74% ของเราดำเนินการธุรกรรมเพียงรายการเดียว การเชื่อมต่อแบบถาวรไม่มีประโยชน์อย่างที่เราทุกคนต้องการ แต่ใน HTTP/2 ตัวเลขดังกล่าวลดลงเหลือ 25% นี่คือชัยชนะที่ยิ่งใหญ่สำหรับการลดโอเวอร์เฮด (HTTP/2 อยู่ใน Firefox, Patrick McManus)

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

การควบคุมการรับส่งข้อมูล

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

ข้อกำหนดข้างต้นช่วยเตือนเกี่ยวกับการควบคุมโฟลว์ TCP ไหม เนื่องจากปัญหาจะเหมือนกันทุกประการ (ดูการควบคุมโฟลว์) อย่างไรก็ตาม เนื่องจากสตรีม HTTP/2 มีการมัลติเพล็กซ์ภายในการเชื่อมต่อ TCP เดียว การควบคุมโฟลว์ TCP จึงไม่ละเอียดเพียงพอ และไม่ได้ให้ API ระดับแอปพลิเคชันที่จำเป็นต่อการควบคุมการนำส่งสตรีมแต่ละรายการ เพื่อแก้ไขปัญหานี้ HTTP/2 จึงมีชุดองค์ประกอบพื้นฐานที่เรียบง่ายที่อนุญาตให้ไคลเอ็นต์และเซิร์ฟเวอร์ใช้การควบคุมโฟลว์ระดับการเชื่อมต่อและสตรีมของตนเอง ดังนี้

  • การควบคุมการไหลมีทิศทาง รีซีฟเวอร์แต่ละรายสามารถเลือกตั้งค่าขนาดหน้าต่างที่ต้องการสำหรับสตรีมแต่ละรายการและการเชื่อมต่อทั้งหมด
  • การควบคุมโฟลว์จะอิงตามเครดิต รีซีฟเวอร์แต่ละรายจะโฆษณาการเชื่อมต่อเริ่มต้นและหน้าต่างควบคุมการไหลของสตรีม (เป็นไบต์) ซึ่งจะลดลงเมื่อผู้ส่งปล่อยเฟรม DATA และเพิ่มขึ้นผ่านเฟรม WINDOW_UPDATE ที่เครื่องรับส่ง
  • ปิดใช้การควบคุมโฟลว์ไม่ได้ เมื่อสร้างการเชื่อมต่อ HTTP/2 เฟรม SETTINGS สำหรับการแลกเปลี่ยนไคลเอ็นต์และเซิร์ฟเวอร์ ซึ่งจะตั้งค่าขนาดหน้าต่างการควบคุมโฟลว์ทั้ง 2 ทิศทาง ค่าเริ่มต้นของหน้าต่างควบคุมโฟลว์จะตั้งค่าไว้ที่ 65,535 ไบต์ แต่ตัวรับสัญญาณจะตั้งค่าหน้าต่างขนาดใหญ่สูงสุดได้ (2^31-1 ไบต์) และคงไว้โดยการส่งเฟรม WINDOW_UPDATE ทุกครั้งที่ได้รับข้อมูล
  • การควบคุมการไหลแบบ Hop-by Hop ไม่ใช่ end-to-end กล่าวคือ ตัวกลางสามารถใช้ การควบคุมการใช้ทรัพยากรและนำกลไกการจัดสรรทรัพยากรไปใช้ ตามเกณฑ์และการเรียนรู้ของตนเอง

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

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

พุชจากเซิร์ฟเวอร์

ฟีเจอร์ใหม่ที่มีประสิทธิภาพอีกอย่างหนึ่งของ HTTP/2 คือความสามารถของเซิร์ฟเวอร์ในการส่งการตอบกลับหลายรายการสำหรับคำขอไคลเอ็นต์รายการเดียว กล่าวคือ นอกจากการตอบกลับคำขอเดิมแล้ว เซิร์ฟเวอร์ยังส่งทรัพยากรเพิ่มเติมไปยังไคลเอ็นต์ได้ (รูปที่ 12-5) โดยไคลเอ็นต์ไม่ต้องขอทีละทรัพยากรอย่างชัดแจ้ง

เซิร์ฟเวอร์เริ่มสตรีมใหม่ (สัญญา) สำหรับทรัพยากรพุช

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

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

  • แคชโดยไคลเอ็นต์
  • มีการใช้ซ้ำในหน้าต่างๆ
  • มัลติเพล็กซ์ร่วมกับทรัพยากรอื่นๆ
  • จัดลำดับความสำคัญโดยเซิร์ฟเวอร์
  • ลูกค้าปฏิเสธ

สัญญาที่จะพุช 101

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

เมื่อไคลเอ็นต์ได้รับเฟรม PUSH_PROMISE ไคลเอ็นต์จะมีตัวเลือกในการปฏิเสธสตรีม (ผ่านเฟรม RST_STREAM) หากต้องการ (ตัวอย่างเช่น กรณีนี้อาจเกิดขึ้นเนื่องจากทรัพยากรอยู่ในแคชอยู่แล้ว) นี่เป็นการปรับปรุงที่สำคัญเหนือ HTTP/1.x ในทางตรงกันข้าม การใช้การผสานรวมทรัพยากร ซึ่งเป็น "การเพิ่มประสิทธิภาพ" ยอดนิยมสำหรับ HTTP/1.x นั้นเทียบเท่ากับ "การบังคับให้พุช" ซึ่งก็คือไคลเอ็นต์เลือกไม่ใช้ ยกเลิก หรือประมวลผลทรัพยากรในบรรทัดทีละรายการไม่ได้

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

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

การบีบอัดส่วนหัว

การโอน HTTP แต่ละครั้งจะมีชุดส่วนหัวที่อธิบายพร็อพเพอร์ตี้ของทรัพยากรที่โอนและพร็อพเพอร์ตี้ ใน HTTP/1.x ระบบจะส่งข้อมูลเมตานี้เป็นข้อความธรรมดาเสมอและจะเพิ่มโอเวอร์เฮด 500-800 ไบต์ต่อการโอนและในบางครั้งอาจเป็นกิโลไบต์หากมีการใช้คุกกี้ HTTP (ดู การวัดและควบคุมโอเวอร์เฮดของโปรโตคอล) ในการลดโอเวอร์เฮดนี้และปรับปรุงประสิทธิภาพ HTTP/2 จะบีบอัดข้อมูลเมตาของคำขอและส่วนหัวการตอบกลับโดยใช้รูปแบบการบีบอัด HPACK ที่ใช้เทคนิคง่ายๆ แต่มีประสิทธิภาพ 2 ข้อดังนี้

  1. วิธีนี้จะช่วยให้เข้ารหัสช่องส่วนหัวที่ส่งผ่านโค้ด Huffman แบบคงที่ ซึ่งจะลดขนาดการโอนแต่ละรายการ
  2. โดยทั้งไคลเอ็นต์และเซิร์ฟเวอร์จะต้องดูแลรักษาและอัปเดตรายการที่จัดทำดัชนีของช่องส่วนหัวที่เห็นก่อนหน้านี้ (กล่าวคือ สร้างบริบทการบีบอัดที่แชร์) ซึ่งจะใช้เป็นข้อมูลอ้างอิงในการเข้ารหัสค่าที่ส่งก่อนหน้านี้อย่างมีประสิทธิภาพ

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

HPACK: การบีบอัดส่วนหัวสำหรับ HTTP/2

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

ความปลอดภัยและประสิทธิภาพของ HPACK

เวอร์ชันแรกๆ ของ HTTP/2 และ SPDY จะใช้ zlib ร่วมกับพจนานุกรมที่กำหนดเองเพื่อบีบอัดส่วนหัว HTTP ทั้งหมด วิธีการนี้ทำให้ขนาดของข้อมูลส่วนหัวที่โอนลดลง 85% ถึง 88% และทำให้เวลาในการโหลดหน้าเว็บเพิ่มขึ้นอย่างมาก

ในลิงก์ DSL แบนด์วิดท์ต่ำซึ่งมีลิงก์อัปโหลดอยู่ที่ 375 Kbps โดยเฉพาะ การบีบอัดส่วนหัวคำขอทำให้เวลาในการโหลดหน้าเว็บดีขึ้นอย่างมากสำหรับบางเว็บไซต์ (กล่าวคือ เว็บไซต์ที่ออกคำขอทรัพยากรจำนวนมาก) เราพบว่าเวลาในการโหลดหน้าเว็บลดลง 45–1,142 มิลลิวินาทีเนื่องจากการบีบอัดส่วนหัว (สมุดปกขาว SPDY, chromium.org)

อย่างไรก็ตาม ในช่วงฤดูร้อนปี 2012 ได้มีการเผยแพร่การโจมตีด้านความปลอดภัย "CRIME" กับอัลกอริทึมการบีบอัด TLS และ SPDY ซึ่งอาจทำให้เกิดการลักลอบใช้เซสชัน ดังนั้น อัลกอริทึมการบีบอัด zlib จึงถูกแทนที่โดย HPACK ที่ออกแบบมาเพื่อ แก้ปัญหาด้านความปลอดภัยที่ค้นพบ มีประสิทธิภาพ และนำไปใช้ได้ง่ายอย่างถูกต้อง และแน่นอนว่าจะทำให้สามารถบีบอัดข้อมูลเมตาของส่วนหัว HTTP ได้เป็นอย่างดี

ดูรายละเอียดทั้งหมดของอัลกอริทึมการบีบอัด HPACK ได้ที่ IETF HPACK - Header Compression for HTTP/2

อ่านเพิ่มเติม