หน้าเว็บ 14kB อาจโหลดได้เร็วกว่าหน้า 15kB มาก (2022)
(endtimes.dev)- หากคงขนาด เว็บไซต์ ไว้ไม่เกิน 14kB จะสามารถ ลดเวลาโหลด ได้อย่างมากเมื่อเทียบกับ 15kB
- ปรากฏการณ์นี้เกิดจาก อัลกอริทึม TCP slow start ซึ่งทำให้เกิดความต่างของความเร็วที่ผู้ใช้รู้สึกได้จากข้อจำกัดของปริมาณข้อมูลที่ส่งได้ในรอบแรก
- 14kB เทียบได้กับ ความจุของแพ็กเก็ต TCP 10 ชุด ที่เซิร์ฟเวอร์ส่วนใหญ่มักส่งในตอนแรก
- ในสภาพแวดล้อมที่มี latency สูง เช่น อินเทอร์เน็ตผ่านดาวเทียม การเพิ่มขึ้นของการไป-กลับ (RTT) อีกหนึ่งครั้งอาจทำให้เกิดความล่าช้าตั้งแต่ 612ms ขึ้นไป
- ในทางปฏิบัติ การใส่คอนเทนต์หลักให้อยู่ต่ำกว่า 14kB หรือจัดวาง ทรัพยากรสำคัญ ไว้ภายใน 14kB แรก จะช่วยเพิ่มประสิทธิภาพเว็บได้อย่างมีประสิทธิผล
ภาพรวมและหลักการสำคัญ
- เป็นที่รู้กันดีว่า เว็บไซต์ ที่มีขนาดเล็กกว่าจะโหลดได้เร็วกว่า
- แต่สิ่งที่คาดไม่ถึงคือเมื่อข้ามจาก 14kB ไปเป็น 15kB จะเกิด ความแตกต่างอย่างมาก ในความเร็วของการตอบสนองครั้งแรก
- ความต่างของความเร็วระหว่างหน้า 15kB กับ 16kB มีน้อยมาก แต่ระหว่าง 14kB กับ 15kB อาจต่างกันได้สูงสุดถึง 612ms
TCP คืออะไร
- Transmission Control Protocol (TCP) ทำงานอยู่บน IP (Internet Protocol) และมีหน้าที่รับประกันความน่าเชื่อถือของแพ็กเก็ต
- เว็บเบราว์เซอร์จะส่งแพ็กเก็ต TCP หลายชุดเมื่อทำ คำขอ HTTP
- หากใช้เพียง IP อย่างเดียวจะไม่สามารถตรวจสอบได้ว่าแพ็กเก็ตไปถึงหรือไม่ ดังนั้น TCP จึงมีฟังก์ชัน ยืนยันการรับแพ็กเก็ต (ACK)
- เซิร์ฟเวอร์ จะส่งแพ็กเก็ตจำนวนเล็กน้อยก่อน และเมื่อได้รับ ACK จาก เบราว์เซอร์ แล้วจึงส่งแพ็กเก็ตเพิ่มเติม
- หากไม่มี ACK ก็จะมีขั้นตอนส่งแพ็กเก็ตซ้ำ
TCP slow start คืออะไร
- TCP slow start คืออัลกอริทึมที่เซิร์ฟเวอร์ค่อย ๆ เพิ่มปริมาณการส่งแพ็กเก็ตทีละขั้นเพื่อประเมินคุณภาพของการเชื่อมต่อเครือข่าย (แบนด์วิดท์)
- ในช่วงเริ่มเชื่อมต่อ เซิร์ฟเวอร์ จะส่งแพ็กเก็ตเพียงเล็กน้อยก่อน (โดยทั่วไปคือ 10 ชุด)
- หากคอมพิวเตอร์ของผู้เข้าชมส่ง ACK กลับมาได้ตามปกติ ปริมาณการส่งแพ็กเก็ตจะเพิ่มขึ้นเป็น สองเท่า
- หากมี ACK หายไป หลังจากนั้นจะส่งแพ็กเก็ตด้วย ความเร็วที่ช้าลง
- รายละเอียดของอัลกอริทึมจริงอาจต่างกันไปตามการติดตั้งใช้งาน แต่แนวคิดหลักเหมือนกัน
เหตุผลของเกณฑ์ 14kB
- เซิร์ฟเวอร์ส่วนใหญ่มักส่ง แพ็กเก็ต TCP 10 ชุด พร้อมกันในช่วง slow start
- แม้ขนาดสูงสุดของแพ็กเก็ต TCP จะเป็น 1500 ไบต์ แต่เมื่อหัก header (40 ไบต์) แล้ว ข้อมูลจริงจะเหลือ 1460 ไบต์
- ดังนั้น 10 x 1460 = 14600 ไบต์ (ประมาณ 14kB) จึงเป็นขีดจำกัดของการส่งครั้งแรก
- หากทำให้เว็บไซต์หรือทรัพยากรสำคัญมีขนาดไม่เกิน 14kB (เมื่อมีการบีบอัด ข้อมูลต้นฉบับอาจมีขนาดระดับหลายสิบ kB) ก็จะแสดงผลได้โดยไม่ต้องรอรอบการไป-กลับเพิ่มเติมในช่วงเริ่มต้น
การไป-กลับหนึ่งครั้งทำให้เกิดความล่าช้าได้มากแค่ไหน
ตัวอย่างอินเทอร์เน็ตผ่านดาวเทียม
- ตัวอย่างของสภาพแวดล้อมที่มี latency สูง คือผู้ใช้งาน อินเทอร์เน็ตผ่านดาวเทียม (เช่น แท่นขุดเจาะน้ำมัน เรือสำราญ)
- เมื่อขอหน้าแรกจากโทรศัพท์ ข้อมูลจะวิ่งผ่าน เราเตอร์ → จานดาวเทียม → ดาวเทียมในอวกาศ → สถานีภาคพื้นดิน → เซิร์ฟเวอร์ โดยแต่ละช่วงใช้เวลา หลายสิบถึงหลายร้อย ms
- การส่งข้อมูลไป-กลับทั้งหมดรวมการเดินทางขึ้นอวกาศสองครั้ง การวิ่งผ่านช่วงเครือข่าย และการประมวลผลของเซิร์ฟเวอร์ ทำให้เกิดความล่าช้าเพิ่มเติมราว 612ms
- หากใช้ HTTPS ก็อาจเพิ่มขึ้นเป็น 1836ms จาก handshake เพิ่มเติม
latency ของเครือข่ายภาคพื้นดิน
- แม้แต่เครือข่ายมือถืออย่าง 2G, 3G ก็อาจมี latency 100~1000ms
- ในสภาวะที่หนาแน่น เซิร์ฟเวอร์โอเวอร์โหลด หรือมี packet loss ก็อาจเกิดความล่าช้าเพิ่มเติมได้
กลยุทธ์การปรับแต่งเว็บไซต์ตามกฎ 14kB
- หัวใจสำคัญคือทำให้เว็บไซต์หรือหน้าเว็บ เล็กที่สุดเท่าที่จะเป็นไปได้
- อุดมคติคือออกแบบให้ปริมาณข้อมูลที่ส่งหลังการบีบอัดของแต่ละหน้า ไม่เกิน 14kB
- เมื่อมีการบีบอัด คอนเทนต์จริงอาจใส่ได้ถึง ~50kB
- หากลดองค์ประกอบที่ไม่จำเป็นส่วนใหญ่ เช่น วิดีโอเล่นอัตโนมัติ ป๊อปอัป ตัวติดตาม และ JS/CSS ที่ไม่จำเป็น ก็สามารถทำได้เพียงพอ
- หากทำทั้งหน้าให้อยู่ใน 14kB ได้ยาก ก็สำคัญมากที่จะต้องจัด ทรัพยากรหลักและคอนเทนต์สำคัญ (เช่น CSS, JS, ข้อความหลัก) ไว้ใน 14kB แรกก่อน
- HTTP header (บีบอัดไม่ได้) และ รูปภาพ (โหลดเฉพาะขั้นต่ำ/เฉพาะส่วนที่มองเห็น หรือใช้ placeholder) ก็รวมอยู่ใน 14kB นี้ด้วย
ข้อยกเว้นของกฎ 14kB และประเด็นของโปรโตคอลสมัยใหม่
- กฎ 14kB ไม่ได้เป็นการสรุปแบบเหมารวมเกินไป แต่ก็มีข้อยกเว้นบางประการ
- เซิร์ฟเวอร์บางตัวขยาย initial window เป็น 30 แพ็กเก็ต
- อาจอนุญาตให้ใช้หน้าต่างที่ใหญ่ขึ้นได้ผ่าน TLS handshake
- สามารถ cache จำนวนแพ็กเก็ตที่ส่งได้ในแต่ละเส้นทาง เพื่อส่งได้มากขึ้นในการเชื่อมต่อครั้งถัดไป
- แม้ใน HTTP/2 แนวปฏิบัติที่เซิร์ฟเวอร์เริ่มจาก TCP slow start ที่ 10 แพ็กเก็ตก็โดยทั่วไปยังไม่เปลี่ยนแปลง
- ใน HTTP/3, QUIC กฎ 14kB ก็ยังถูกแนะนำอย่างเป็นทางการ
สรุปและเอกสารอ้างอิง
- สามารถดูเหตุผลทางเทคนิคและข้อมูลอธิบายเพิ่มเติมได้จากลิงก์ต่าง ๆ
- เผยแพร่ครั้งแรก: 2022-08-25, แก้ไขล่าสุด: 2022-08-26, ผู้เขียน: Nathaniel, แท็กที่เกี่ยวข้อง: ประสิทธิภาพเว็บ, HTTP, TCP
ลิงก์อ้างอิง
- ข้อมูลเพิ่มเติมเกี่ยวกับโครงสร้าง Ethernet frame และ TCP header, latency และ bandwidth, รวมถึงสเปกของ TCP/QUIC
1 ความคิดเห็น
ความเห็นจาก Hacker News
นักพัฒนาซอฟต์แวร์ควรให้ความสนใจกับชั้นสื่อสารมากกว่านี้ โดยเฉพาะประเด็นเรื่องความน่าเชื่อถือและ latency ของ 3G/5G ที่ผู้เขียนชี้ไว้ได้อย่างน่าสนใจ วิทยุมักมีการ retransmit เกิดขึ้นแทบตลอดเวลา และในการสื่อสาร HTTP ส่วนใหญ่ แพ็กเก็ตต้องมาถึงตามลำดับก่อน UI จะอัปเดตได้ จริง ๆ แล้วแม้แต่ REST request เดียวก็จะเป็นแพ็กเก็ตเดียวจริง ๆ ก็ต่อเมื่อทั้ง request และ response มีขนาดต่ำกว่า 1400 ไบต์เท่านั้น ถ้าเกินกว่านั้น request ที่ดูเหมือน “ครั้งเดียว” ก็จริง ๆ แล้วถูกแยกเป็นหลายแพ็กเก็ต หากมีแพ็กเก็ตใดแพ็กเก็ตหนึ่งมีปัญหา ทุกแพ็กเก็ตก็ต้องมาถึงตามลำดับก่อนหน้าจอจะรีเฟรชได้ถูกต้อง ถ้าอยากลองทดลองดู ให้เปิดโหมด 3G และ packet loss ใน Chrome DevTools แล้วทดสอบ คุณจะเห็นว่าแค่ optimization เล็ก ๆ อย่างเดียวก็ช่วยให้ UI ตอบสนองดีขึ้นมาก นี่จึงเป็นเหตุผลที่ฟังขึ้นมากว่าทำไม API และ UI ควรทำให้เล็กที่สุดเท่าที่เป็นไปได้
หน้าโฮมเพจของผมมีขนาดส่งข้อมูล 7.0kB แบบบีบอัด
เป้าหมาย 14kB ค่อนข้างท้าทาย แต่แนวคิดการจำกัดให้อยู่ภายใน 10 แพ็กเก็ตแรกก็น่าสนใจ มีโปรเจกต์อย่าง 512kb.club ที่โฟกัสเรื่องขนาดเว็บไซต์แบบเดียวกัน เว็บไซต์นั้นเปรียบเทียบขนาดไซต์เหมือนคะแนนกอล์ฟ เว็บไซต์ของผม(anderegg.ca) ก่อนสมัครถูกวัดได้ 71kB รวมทุก resource โปรเจกต์นี้ยังทำให้ผมได้รู้จัก Cloudflare Radar ซึ่งมีเครื่องมือที่ดีสำหรับวิเคราะห์เว็บไซต์และวัดขนาดหน้า แม้เป้าหมายหลักจะเป็นแดชบอร์ดภาพรวมของอินเทอร์เน็ต แต่ก็มีเครื่องมือวิเคราะห์ขนาดหน้าเว็บรวมอยู่ด้วย
ถ้าอยากทดลองเรื่องนี้ให้สนุกขึ้นอีกหน่อย ขนาด initial window (IW) สามารถตั้งจากฝั่งเซิร์ฟเวอร์ได้ ตัวอย่างเช่นปรับได้แบบนี้
สิ่งที่อธิบายในบทความด้านล่างก็ใช้ได้เหมือนกัน: บล็อก Cloudflare - ISP รัสเซียปล่อยผ่านแค่ 16KB แรกจนการท่องเว็บส่วนใหญ่ใช้งานไม่ได้. จากการวิเคราะห์ของ Cloudflare ตอนนี้ ISPs ในรัสเซียกำลัง throttle อินเทอร์เน็ตของผู้ใช้ในประเทศ ทำให้โหลดได้เพียง 16KB แรกต่อ web asset เท่านั้น
คนที่ไม่รู้ว่า TCP Slow Start คืออะไร กับคนที่ใส่ใจจนถึงขั้นต้องกังวลเรื่องความหน่วงการโหลดเว็บไซต์ระดับจิ๋ว ๆ มีส่วนทับซ้อนกันน้อยมาก สตาร์ตอัปควรโฟกัสกับการเป็นสตาร์ตอัปก่อน และมีแต่บริษัทใหญ่เท่านั้นที่พอมีแรงไปหมกมุ่นกับ optimization แบบนี้
หน้าโฮมเพจของผมมีขนาด 17.2KB! (ไม่รวม dependencies) ผม optimize หน้าเว็บส่วนตัวอย่างหนักจริง ๆ จนได้คะแนน Lighthouse เต็ม 100 ด้วย เดิมคิดว่าเป็นไปไม่ได้แต่ก็ทำสำเร็จ และบอกไว้ก่อนว่าทำด้วย Rails การ optimize แบบนี้คุ้มค่าจริง ๆ ประสบการณ์ของหน้าเว็บที่เปิดขึ้นมาไวทันใจโดยไม่รู้สึกหน่วงนั้นน่าพอใจมากในตัวมันเอง
ผมคิดว่าบทความนี้มีจุดอ่อนเชิงตรรกะอยู่สองข้อ
คนยุคนี้มีแนวโน้มสร้างแม้แต่เว็บไซต์ static ธรรมดาด้วยเฟรมเวิร์กอย่าง Next.js ทำให้อดเสียดายไม่ได้ที่ยุค HTML+CSS+js กำลังเลือนหายไป
นอกจาก latency แล้ว การลดการใช้ทรัพยากรให้น้อยที่สุดยังเป็นเงื่อนไขสำคัญของอนาคตที่ยั่งยืนด้วย ผลกระทบของเครือข่ายต่อสิ่งแวดล้อมก็ไม่ได้เล็กน้อยเลย น่าเสียดายที่บรรยากาศในคอมเมนต์ดูประชดประชันกันอยู่บ้าง แม้ optimization นี้จะไม่ใช่ทางออกสูงสุดของทุกอย่าง แต่ผมอยากให้มีการเน้นเรื่องการลดการใช้พลังงานมากกว่านี้