2 điểm bởi GN⁺ 2025-07-20 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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)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

 
GN⁺ 2025-07-20
Ý 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

    • /
    • main.css
    • favicon.png
    • Tổng cộng 7.0kB Danh sách blog và toàn bộ website được tạo bằng static site generator tự viết của tôi (công khai: site.lisp, dùng Common Lisp). Với các bài viết về toán, tôi đang dùng KaTeX để render phía client, và trường hợp này làm tăng thêm 347.5kB
    • katex.min.css 23.6kB
    • katex.min.js 277.0kB
    • auto-render.min.js 3.7kB
    • KaTeX_Main-Regular.woff2 26.5kB
    • KaTeX_Main-Italic.woff2 16.7kB
    • Tổng cộng thêm 347.5kB Tôi đang cân nhắc một lúc nào đó sẽ chuyển KaTeX sang render phía server. Blog này là dự án đam mê cá nhân của tôi từ thời ở ký túc xá đại học. Tôi tự viết toàn bộ HTML, template và cả CSS, luôn cẩn thận chỉ đưa vào mỗi trang những gì thật sự cần thiết để giữ dung lượng nhỏ
    • Trang chủ của tôi
    • Tập hợp bài viết toán học
      • Không phải là bảo đừng dùng cách tốt hơn, nhưng độ trễ do render phía client khi tải các component động như biểu thức LaTeX thì với người dùng bình thường hầu như không thể nhận ra, hoặc thật sự không nhận ra. Tối ưu quá mức cũng là vấn đề. Việc theo đuổi hiệu năng kiểu SEO này nếu không phải dịch vụ có hàng triệu lượt xem thì lợi ích so với thời gian bỏ ra là không đáng kể. Nó giống như lo cả khí động học khi đang điều khiển một con thuyền không người lái bằng thủy triều giữa biển. Với nguồn lực hữu hạn, nếu xét tổng chi phí và lợi ích thì tối ưu không phải lúc nào cũng là lựa chọn tốt nhất
      • Nếu nội dung toán học không nhiều mà vẫn muốn dùng KaTeX, thì có thể cân nhắc thay thế bằng MathML (mathml-core)
      • Tôi không hiểu vì sao lại phải render công thức toán hay biểu thức LaTeX bằng js phía client. Tại sao không chuyển sẵn sang HTML/CSS và đưa vào ở trạng thái đã render trước?
      • Một ý tưởng khác là tải thư viện nặng sau khi trang đã render ban đầu, hoặc chỉ tải đồ họa công thức dưới dạng SVG khi nó xuất hiện trong viewport. Ý kiến cá nhân của tôi
  • 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

    • Từ góc nhìn người dùng, tôi muốn hỏi 500kB còn lại dùng để làm gì? Tôi chỉ cần 90% là văn bản, phần còn lại nếu là đồ họa vector cũng đủ rồi. Chỉ với 14 kB đã chứa được khá nhiều văn bản và đồ họa, vậy 500 còn lại để làm gì?
    • 512kb là một chuẩn thực tế hơn. Tôi cũng áp dụng chuẩn này cho website của mình. Website ở mức 14kb đã vượt khỏi chuẩn thông thường của web rồi
    • Với website cá nhân thì 512kb hoàn toàn có thể đạt được. Mục tiêu tiếp theo của tôi là 99kb (dưới 100kb). Chỉ cần bỏ ra vài cuối tuần là ổn. Site của tôi đang ở hạng Orange trong mức 512kb
  • 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

    • ip route change default via <gw> dev <if> initcwnd 20 initrwnd 20 Tìm kiếm thì thấy hiện nay có CDN cho initial window tới 30 gói (45kb)
    • 13 năm trước, ngay cả 10 gói cũng bị xem là “gian lận”. Xem thêm ở đâyblog Ben Strong (bản lưu trữ)
    • Tôi muốn biết có tài liệu nào chứng minh initial window của CDN là 30 gói không
    • Cũng có thể cứ đặt thành 1000 gói như một “công dân xấu”... nhưng nhược điểm là ai đó dùng dial-up hoặc kết nối bị bufferbloat có thể gặp nghẽn cổ chai
  • 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

    • Nếu cứ tiếp cận kiểu “vì đang tập trung vào việc quan trọng hơn nên không có thời gian lo tối ưu hiệu năng”, thì sẽ chẳng bao giờ để tâm tới nó cả. Vì thế mà phần lớn app và site ngày nay chậm chạp và tệ hại
    • Nếu điều đó đúng thì phần mềm của những nơi như Microsoft lẽ ra lúc nào cũng phải hoàn hảo và chạy hiệu quả nhất
    • Về mặt khái niệm thì nghe có vẻ đúng. Nhưng nếu Evan Wallace của Figma không ám ảnh với hiệu năng thì Figma đã không thể trở thành như hiện nay. Có lúc chính “hiệu năng” lại là tính năng cốt lõi của sản phẩm
    • Đây không nhất thiết là chuyện phải chọn, mà có thể làm cho nó trở thành mặc định. Tôi làm cả demo 1 tỷ ô lưới và demo checkbox[1] đều bằng datastar mà chỉ hơn 10kb một chút. Khác biệt trên mạng di động và 3G là rất lớn. Theo thử nghiệm của tôi, vượt 14kb thì trên kết nối chất lượng thấp mất thêm 3 giây. Nhờ maintainer của datastar còn để ý cả TCP slow start nên tôi chẳng cần tốn công mà vẫn được hưởng lợi theo
    • Tôi không nghĩ quy mô công ty có liên quan lớn đến tối ưu hiệu năng. Thậm chí nhiều công ty lớn còn chậm hơn
  • 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

    • Khi trải nghiệm news.ycombinator.com tải gần như tức thì, cảm giác tâm lý cũng cực kỳ dễ chịu, tới mức cứ rảnh một chút là lại tự động mở ra
    • Tôi đã tối ưu cực kỳ mạnh phần mã template dùng cho hàng nghìn website để đạt Lighthouse 100/100/100/100. Trên mobile cũng 100 tuyệt đối. Lần tải đầu lớn hơn nhiều so với 17.2kB, khoảng 120kB, nhưng bí quyết là loại bỏ mọi HTTP request không cần thiết, chỉ chạy JS cho vùng “above-the-fold”, phần còn lại thì lazy eval, defer và trì hoãn tải tối đa. JS/CSS được inline, widget bên thứ ba cũng dùng kiểu “facade” như icon popup để hoãn request thật về sau. Backend SSR cũng góp phần lớn. Ngay cả nền video Vimeo cũng đạt 100 điểm, nhưng với Youtube thì không thể. Cách để đạt điểm hoàn hảo là đọc kết quả Lighthouse rồi viết lại toàn bộ codebase. Nhờ vậy mà mọi phàn nàn của client về tốc độ biến mất hoàn toàn, và điều này cũng tạo lợi thế cạnh tranh lớn cả về SEO lẫn điểm số thực tế
    • Rails không liên quan trực tiếp tới tối ưu render. Chúc mừng điểm Lighthouse hoàn hảo
  • Tôi nghĩ bài viết có hai điểm yếu về mặt logic

    1. Có công thức nói rằng trong liên lạc vệ tinh mất khoảng 1600ms để gửi một gói, nhưng đó là cơ sở yếu cho quy tắc 14kb. Không có đối chiếu với website lớn nên không chứng minh được 10 gói ≠ 16 giây
    2. Bài nói cả hình ảnh trên trang cũng tính vào quy tắc 14kb, nhưng có bao nhiêu trường hợp ảnh được inline ngay lúc tải đầu? Thực tế đây là ngoại lệ rất hiếm, nên cần nói rõ hơn rằng điều này không áp dụng cho 99.9% trường hợp - “<i>Trường hợp ảnh được inline?</i>” thì ví dụ điển hình là thumbnail độ phân giải thấp chỉ xuất hiện ở màn hình đầu, thêm CSS blur rồi fade in ảnh thật bất đồng bộ về sau. Nếu làm đúng thì chỉ tốn thêm khoảng 1~200 byte. Tôi đã áp dụng trên blog của mình, và các nền tảng như Wordpress, Medium cũng dùng nhiều. Chủ yếu là mẹo hyper-optimization cho frontend thương mại - Tôi cũng không đồng ý với giả định rằng đa số người dùng dùng kết nối vệ tinh độ trễ thấp, và trong bối cảnh mọi website đều nặng tới vài MB thì lại cho rằng chỉ riêng trang của tôi là không chịu nổi
  • 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

    • Đồng ý. Tôi cũng đã làm đủ kiểu site tối thiểu tài nguyên, tự tối ưu JavaScript, site theo quy tắc 14kb, nhưng cách này kéo theo ràng buộc về thiết kế và kiến trúc. Khi tính năng tăng lên thì các quyết định “tối thiểu hóa” trước đó đều trở thành nợ kỹ thuật. Đa số người ta lý tưởng hóa “web thuần không framework”, rồi tới một lúc nhận ra nó còn khổ hơn. Nhưng nếu dùng framework JS isomorphic thì có thể bắt đầu bằng trang tĩnh, tối ưu vừa phải, rồi khi cần chuyển sang thick client JS
    • Thực ra xu hướng đã đổi chiều trở lại. Phần lớn framework ngày nay đều hỗ trợ website tĩnh rất tốt. Những cái như Astro thậm chí sinh ra để làm site tĩnh
    • Giờ mới nhận ra à, nhưng thật ra chuyện này đã kéo dài từ trước cả thời jQuery bùng nổ vào khoảng 2010 rồi
    • Next.js tối ưu bundle code rất mạnh, phù hợp để triển khai trên lambda hay server nhỏ. Site tĩnh làm bằng Next cũng có bundle rất nhỏ
  • 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

    • Phần lớn lưu lượng Internet là video streaming. Tối ưu vài MB ở trang web thì hầu như chẳng đáng kể. Hiệu quả bản thân nó vẫn đáng bàn, nhưng nỗ lực tối ưu ở mọi nơi có thể lại làm tiêu hao nguồn lực vốn nên dành cho các lĩnh vực thật sự cần tối ưu
    • Đây còn chẳng phải trái thấp dễ hái. Trong lúc tối ưu để tiết kiệm 1~2mWh cho một trang web, thì chỉ một truy vấn công cụ tìm kiếm đã tốn gấp 100 lần, một lần dùng chatbot còn tốn gấp 10.000 lần. Caching hay lazy loading cũng đã giảm nhẹ đáng kể rồi
    • Việc bận tâm giảm kích thước trang gần như là chuyện vô ích. Lượng điện tiêu thụ cho duyệt web cả năm, kể cả nhân hệ số an toàn lên 10 lần, vẫn còn thấp hơn rất nhiều so với năng lượng để làm ra một chiếc hamburger. Thậm chí tác động môi trường từ việc một lập trình viên ăn một bữa salad trong một tuần thay vì tối ưu còn lớn hơn
    • Hoàn toàn đồng ý. Hồi trước tôi từng đến BBC và sốc khi thấy chỉ một bài viết văn bản nhỏ mà lưu tới 120MB trong cache. Nó thúc đẩy văn hóa lãng phí và tiêu tốn năng lượng vô ích. Tôi cũng làm website của mình tối giản nhất có thể, và khi upload YouTube thì chỉ dùng 1080P thay vì 4K. 4K, 8K thật sự không cần phải tồn tại. Mọi người hay chỉ nói đến chuyện bổ sung thêm vài MW điện mặt trời, nhưng thật ra nên tưởng tượng xem việc “sản xuất ít hơn” sẽ tốt đến mức nào. Tôi nhớ quy mô web nhỏ thời modem 56K; chắc hẳn đã từng có một điểm cân bằng nào đó ở giữa, nhưng giờ thì chúng ta đã vượt quá rất xa
    • Mọi người chỉ bắt đầu quan tâm khi nó ảnh hưởng trực tiếp tới bản thân họ. Tôi cũng là người có cân nhắc tới môi trường. Có phản bác rằng AI còn tệ hơn, nhưng thật ra AI cũng crawl những trang nặng như thế này. Và chuẩn 14kb vẫn chưa tới 1% payload trung bình của một trang mobile hiện nay