- Giữ kích thước website ở mức 14kB trở xuống có thể rút ngắn đáng kể thời gian tải so với khi là 15kB
- Hiện tượng này xảy ra do thuật toán TCP slow start, khi giới hạn lượng dữ liệu truyền đầu tiên tạo ra khác biệt rõ rệt về tốc độ cảm nhận
- 14kB tương ứng với dung lượng của 10 gói TCP mà phần lớn máy chủ gửi đi lúc ban đầu
- Trong các môi trường độ trễ cao như Internet vệ tinh, chỉ một vòng khứ hồi (RTT) bổ sung cũng có thể gây ra độ trễ hơn 612ms
- Trên thực tế, việc đưa nội dung chính xuống dưới 14kB hoặc đặt tài nguyên quan trọng trong 14kB đầu tiên là cách tối ưu hiệu năng web rất hiệu quả
Tổng quan và nguyên lý chính
- Website càng nhỏ thì tải càng nhanh là điều đã được biết đến rộng rãi
- Nhưng việc tốc độ phản hồi đầu tiên tạo ra khác biệt mang tính bước ngoặt khi vượt từ 14kB sang 15kB là điều không ngờ tới
- Chênh lệch tốc độ giữa trang 15kB và 16kB là rất nhỏ, nhưng giữa 14kB và 15kB có thể lên tới 612ms
TCP là gì
- Transmission Control Protocol (TCP) hoạt động phía trên IP (Internet Protocol) và chịu trách nhiệm bảo đảm độ tin cậy của gói tin
- Khi gửi yêu cầu HTTP, trình duyệt web sẽ truyền nhiều gói TCP
- Nếu chỉ dùng IP thì không thể biết gói tin đã đến nơi hay chưa, nên TCP cung cấp cơ chế xác nhận nhận gói (ACK)
- Máy chủ sẽ gửi trước một lượng nhỏ gói tin, và sau khi nhận ACK từ trình duyệt thì mới gửi thêm các gói tiếp theo
- Nếu không có ACK, quy trình truyền lại gói sẽ được thực hiện
TCP slow start là gì
- TCP slow start là thuật toán mà máy chủ tăng dần lượng gói được gửi để xác định chất lượng kết nối mạng (băng thông)
- Ở giai đoạn đầu kết nối, máy chủ chỉ gửi một lượng nhỏ gói tin, thường là 10 gói
- Nếu máy tính của người truy cập gửi ACK bình thường, lượng gói gửi đi sẽ được tăng gấp đôi
- Nếu xảy ra thiếu ACK, về sau dữ liệu sẽ được gửi với tốc độ chậm hơn
- Thuật toán thực tế có thể khác nhau đôi chút tùy theo từng cách triển khai, nhưng khái niệm là như nhau
Cơ sở của mốc 14kB
- Phần lớn máy chủ trong slow start sẽ gửi 10 gói TCP trong một lần
- Kích thước tối đa của một gói TCP là 1500 byte, nhưng sau khi trừ header (40 byte) thì dữ liệu thực còn 1460 byte
- Vì vậy, 10 x 1460 = 14600 byte (khoảng 14kB) là giới hạn cực đại của đợt truyền đầu tiên
- Nếu website hoặc tài nguyên quan trọng được giữ ở mức 14kB trở xuống (khi có nén thì dữ liệu gốc có thể ở mức vài chục kB), nội dung có thể hiển thị mà không phải chịu thêm độ trễ khứ hồi ở giai đoạn đầu
Một vòng khứ hồi có thể gây ra độ trễ lớn đến mức nào
Ví dụ Internet vệ tinh
- Ví dụ điển hình của môi trường độ trễ cao là người dùng Internet vệ tinh (như trên giàn khoan dầu, tàu du lịch, v.v.)
- Khi điện thoại gửi yêu cầu tới trang chủ, dữ liệu đi qua router → ăng-ten vệ tinh → vệ tinh ngoài không gian → trạm mặt đất → máy chủ, và mỗi chặng có thể mất vài chục đến vài trăm ms
- Toàn bộ một vòng truyền nhận gồm hai lần đi-về với vệ tinh, các chặng mạng và cả xử lý phía máy chủ, tạo thêm khoảng 612ms độ trễ
- Nếu dùng HTTPS, do có thêm bắt tay, độ trễ có thể tăng lên 1836ms
Độ trễ của mạng mặt đất
- Ngay cả trên các mạng di động như 2G, 3G, độ trễ cũng có thể nằm trong khoảng 100~1000ms
- Các tình huống như tắc nghẽn, quá tải máy chủ hay mất gói cũng có thể làm phát sinh thêm độ trễ
Chiến lược tối ưu website với quy tắc 14kB
- Cốt lõi là làm cho website hoặc trang nhỏ nhất có thể
- Lý tưởng nhất là thiết kế sao cho dung lượng truyền đã nén của mỗi trang không vượt quá 14kB
- Khi có nén, nội dung thực tế có thể bao gồm tới ~50kB
- Nếu giảm bớt video tự phát, popup, tracker, JS/CSS không cần thiết và các thành phần dư thừa khác thì hoàn toàn có thể đạt được mục tiêu này
- Nếu khó triển khai toàn bộ trong 14kB, điều quan trọng là ưu tiên đặt tài nguyên cốt lõi và nội dung chính (CSS, JS, văn bản chính, v.v.) vào 14kB đầu tiên
- HTTP header (không nén được) và hình ảnh (chỉ tải phần thật sự cần thiết/phần đang hiển thị hoặc dùng placeholder) cũng được tính trong giới hạn 14kB
Ngoại lệ của quy tắc 14kB và các vấn đề với giao thức hiện đại
- Quy tắc 14kB không phải là một sự khái quát hóa quá mức, nhưng vẫn có một vài ngoại lệ
- Một số máy chủ mở rộng cửa sổ ban đầu lên 30 gói
- Bắt tay TLS có thể cho phép một cửa sổ lớn hơn
- Có thể cache số lượng gói có thể truyền theo từng route để gửi nhiều hơn ở lần kết nối sau
- Ngay cả với HTTP/2, thông lệ máy chủ bắt đầu từ 10 gói do TCP slow start nhìn chung vẫn không thay đổi
- Với HTTP/3, QUIC, quy tắc 14kB cũng được khuyến nghị chính thức
Tóm tắt và tài liệu tham khảo
- Có thể xem các cơ sở kỹ thuật và tài liệu giải thích bổ sung qua từng liên kết
- Xuất bản lần đầu: 2022-08-25, cập nhật gần nhất: 2022-08-26, tác giả: Nathaniel, thẻ liên quan: hiệu năng web, HTTP, TCP
Liên kết tham khảo
- Thêm tài liệu về cấu trúc khung Ethernet và TCP header, độ trễ và băng thông, cũng như đặc tả TCP/QUIC
1 bình luận
Ý kiến Hacker News
Các nhà phát triển phần mềm cần quan tâm hơn tới tầng truyền thông, đặc biệt là những điểm tác giả nêu về độ tin cậy và độ trễ của 3G/5G rất đáng chú ý. Radio gần như luôn có truyền lại, và trong hầu hết giao tiếp HTTP thì các gói phải đến đúng thứ tự thì UI mới được cập nhật. Trên thực tế, ngay cả một yêu cầu REST đơn lẻ cũng chỉ thực sự là một gói khi cả request và response đều dưới 1400 byte. Nếu lớn hơn thì yêu cầu “đơn lẻ” đó thực ra bị tách thành nhiều gói. Chỉ cần một trong số đó có vấn đề thì tất cả các gói vẫn phải đến đủ và đúng thứ tự thì màn hình mới cập nhật đúng. Nếu muốn thử nghiệm, hãy bật chế độ 3G và packet loss trong Chrome DevTools để test, bạn sẽ thấy chỉ một tối ưu nhỏ cũng có thể cải thiện mạnh độ phản hồi của UI. Vì vậy, có lý do thuyết phục để giữ API và UI nhỏ nhất có thể
Trang chủ của tôi có dung lượng truyền tải 7.0kB sau khi nén
Mục tiêu 14kB khá thách thức, nhưng ý tưởng giới hạn trong 10 gói đầu tiên cũng thú vị. Có dự án 512kb.club cũng tập trung vào dung lượng website như tôi. Đó là nơi so sánh kích thước site như điểm golf. Site của tôi (anderegg.ca) trước khi đăng ký có tổng dung lượng mọi tài nguyên là 71kB. Nhờ dự án này tôi cũng biết tới Cloudflare Radar, nơi có công cụ tốt để phân tích site và đo dung lượng trang. Mục đích chính là dashboard toàn bộ Internet, nhưng cũng có kèm công cụ phân tích page size
Nếu muốn thử nghiệm chuyện này thú vị hơn, kích thước initial window (IW) có thể được cấu hình ở phía server. Ví dụ có thể chỉnh như sau
Những gì bài dưới đây giải thích cũng áp dụng được: Blog Cloudflare - ISP Nga chỉ cho phép tới 16KB khiến phần lớn việc duyệt web trở nên bất khả thi. Theo phân tích của Cloudflare, các ISP Nga đang throttle Internet của người dùng trong nước để mỗi tài nguyên web chỉ tải được 16KB đầu tiên
Giao điểm giữa những người không biết TCP Slow Start là gì và những người quan tâm tới mức soi từng chút độ trễ khi tải website là rất nhỏ. Startup nên tập trung làm startup trước, chỉ các công ty lớn mới có dư sức ám ảnh với kiểu tối ưu này
Trang chủ của tôi là 17.2KB! (không tính dependency) Tôi thật sự tối ưu rất kỹ cho trang cá nhân và còn đạt Lighthouse 100 điểm tuyệt đối. Trước đây tôi nghĩ là không thể nhưng đã làm được. Nhân tiện, nó được viết bằng Rails. Kiểu tối ưu này thật sự đáng làm. Trải nghiệm một trang hiện ra nhanh như chớp, không có cảm giác ì ạch, bản thân nó đã rất thỏa mãn rồi
Tôi nghĩ bài viết có hai điểm yếu về mặt logic
Thế hệ hiện nay có xu hướng làm cả website tĩnh đơn giản bằng framework như Next.js. Tôi thấy hơi tiếc vì thời HTML+CSS+js dường như đang lùi dần
Không chỉ độ trễ, việc giảm thiểu tiêu thụ tài nguyên là điều thiết yếu cho một tương lai bền vững. Tác động của mạng tới môi trường cũng hoàn toàn không nhỏ. Tôi thấy tiếc vì không khí bình luận hơi mang tính mỉa mai. Dù tối ưu này chưa phải giải pháp tối hậu, nhưng hiệu quả giảm tiêu thụ năng lượng đáng lẽ nên được nhấn mạnh hơn