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

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

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

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

ทำไมไม่ใช้ HTTP/1.2

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

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

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

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

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

หลังจากการประกาศครั้งแรกไม่นาน Mike Belshe และ Roberto Peon วิศวกรซอฟต์แวร์ที่ Google ทั้ง 2 คนได้แชร์ผลลัพธ์ เอกสารประกอบ และซอร์สโค้ดสำหรับเวอร์ชันทดลองของโปรโตคอล 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 จะทำหน้าที่เป็น Branch ทดลองที่ใช้เพื่อทดสอบฟีเจอร์ใหม่และข้อเสนอสำหรับมาตรฐาน 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 รายการเท่านั้น (คิวการตอบกลับ) ต่อการเชื่อมต่อ ที่แย่กว่านั้นคือยังส่งผลให้เกิดการบล็อกแบบ Head of Line และการใช้การเชื่อมต่อ TCP ที่สำคัญได้อย่างไม่มีประสิทธิภาพอีกด้วย

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  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 หลายรายการกับสตรีมมัลติเพล็กซ์แบบคู่ขนานอีกต่อไป โดยแต่ละสตรีมจะแบ่งออกเป็นหลายเฟรม โดยใส่แทรกและจัดลำดับความสำคัญได้ ด้วยเหตุนี้ การเชื่อมต่อ 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 ของ Exchange สำหรับไคลเอ็นต์และเซิร์ฟเวอร์ ซึ่งจะกำหนดขนาดหน้าต่างควบคุมโฟลว์สำหรับทั้ง 2 ทิศทาง ค่าเริ่มต้นของหน้าต่างควบคุมโฟลว์ตั้งค่าไว้ที่ 65,535 ไบต์ แต่ผู้รับสามารถกำหนดขนาดหน้าต่างสูงสุดเป็นขนาดใหญ่ (2^31-1 ไบต์) และคงไว้ได้โดยส่งเฟรม WINDOW_UPDATE เมื่อใดก็ตามที่ได้รับข้อมูล
  • การควบคุมการไหลเวียนเป็นฮอพทีละฮอพ ไม่ใช่จากต้นทางถึงปลายทาง กล่าวคือ ตัวกลางสามารถใช้ทรัพยากรดังกล่าวเพื่อควบคุมการใช้ทรัพยากรและนำกลไกการจัดสรรทรัพยากรไปใช้ตามเกณฑ์และการเรียนรู้ของตนเอง

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

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

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

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

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

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

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

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

PUSH_PROMISE 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–1142 มิลลิวินาทีเพียงเพราะการบีบอัดส่วนหัว (เอกสารไวท์เปเปอร์ SPDY, chromium.org)

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

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

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