Trình duyệt không gửi được ping thô nên bài đo chỉ tính giờ các lần truyền HTTP. Xem khởi động, kích thước tải, luồng và trung vị định hình con số ra sao.
Điểm chính
- Một trang web không thể gửi ping ICMP hay mở socket thô, nên mọi bài đo tốc độ trên trình duyệt đều dựng từ các lần truyền HTTP hoặc WebSocket được tính giờ bằng đồng hồ.
- Thông lượng đơn giản là số byte nhận được chia cho thời gian trôi qua, nhưng chỉ có ý nghĩa sau khi kết nối đã tăng tốc, nên bài đo có lần truyền khởi động và bỏ đi vài giây đầu.
- Các lựa chọn thiết kế (một luồng hay nhiều luồng, kích thước tải, trung vị hay lần chạy tốt nhất) làm thay đổi con số chính trên cùng một đường truyền.
- "Ping" trong trình duyệt là một vòng HTTP đi về, nên gồm cả thời gian xử lý của máy chủ, không chỉ đường truyền.
Bài đo tốc độ trên trình duyệt đo kết nối bằng cách truyền byte thật qua HTTP (hoặc WebSocket) và tính giờ bằng đồng hồ độ phân giải cao. Tốc độ tải xuống là lượng dữ liệu nhận được chia cho thời gian; độ trễ là thời gian của một yêu cầu và phản hồi rất nhỏ. Mọi thứ còn lại trong thiết kế bài đo đều để phép chia đơn giản này trung thực. Bài viết này chỉ nói về cơ chế: cái gì được truyền, cái gì được tính giờ, cái gì bị bỏ, và một con số ra đời thế nào. Về lý do kết quả khác nhau giữa các lần chạy hay công cụ, xem vì sao kết quả kiểm tra tốc độ thay đổi; về ý nghĩa của băng thông, độ trễ và jitter, xem giải thích các chỉ số.
Trình duyệt thực sự đo được gì?
Trang web chạy trong một môi trường cô lập (sandbox). Nó không thể gửi yêu cầu echo ICMP (lệnh ping kinh điển), không mở được socket thô và không thấy các gói tin. Nó có thể gọi fetch(), XMLHttpRequest hoặc WebSocket và đọc đồng hồ. Đồng hồ chuẩn là performance.now(), bộ đếm đơn điệu không bị ảnh hưởng khi chỉnh giờ hệ thống.
Một ràng buộc này giải thích phần lớn thiết kế:
- Độ trễ là một vòng HTTP đi về. Trình duyệt tính giờ một yêu cầu nhỏ cho đến khi phản hồi đến. Thời gian đó gồm xử lý của máy chủ và xử lý kết nối, nên thường cao hơn một chút so với ping ICMP tới cùng máy chủ.
- Thông lượng được quan sát từ phía trang. Bài đo đếm byte khi chúng đến (hoặc khi tải lên xong) rồi chia cho thời gian. Nó đo lượng dữ liệu trang thực sự chuyển được, đúng là con số quan trọng khi dùng web.
Vì sao bài đo cần khởi động
Kết nối TCP mới không chạy hết tốc độ ngay. Cơ chế kiểm soát tắc nghẽn bắt đầu bằng cửa sổ nhỏ rồi tăng dần khi nhận được xác nhận, giai đoạn này gọi là khởi đầu chậm (slow start). Bài đo chỉ tính giờ một tệp nhỏ chủ yếu đo giai đoạn tăng tốc này và đánh giá thấp đường truyền.
RFC 6349, khung kiểm thử thông lượng TCP của IETF, cũng nhấn mạnh điều đó: cái cần biết là thông lượng ổn định mà đường truyền duy trì được, không phải vài vòng đầu tiên. Trên thực tế, các bài đo xử lý bằng hai cách: gửi một yêu cầu khởi động dùng một lần có kết quả bị bỏ, và dùng tải đủ lớn để giai đoạn tăng tốc chỉ chiếm một phần nhỏ tổng thời gian.
Điều này cũng giải thích vì sao tệp rất nhỏ là phép thử băng thông kém. Phản hồi 1 KB kết thúc trước khi cửa sổ kịp mở, nên nó nói về độ trễ chứ không phải dung lượng.
Kích thước tải thích ứng
Kích thước tệp cố định không hợp với hầu hết mọi người. Tệp 50 MB mất hàng phút trên đường di động yếu; trên cáp quang, tệp 1 MB xong trước khi kết nối kịp tăng tốc. Cách thường dùng là bắt đầu nhỏ và tăng tải đến khi một lần truyền kéo dài đúng thời lượng mục tiêu, thường vài giây. Đường chậm vẫn ngắn, còn đường nhanh nhận đủ dữ liệu để đạt trạng thái ổn định.
Một luồng hay nhiều luồng?
Ở đây các thiết kế thực sự khác nhau.
- Nhiều luồng song song. Nhiều bài đo thương mại mở cùng lúc nhiều kết nối TCP. Cách này lấp đầy những đường có tích băng thông-độ trễ lớn (nhanh và xa) mà một luồng đơn có thể không bão hòa, và thường báo đỉnh cao hơn.
- Một luồng duy nhất. NDT của M-Lab, ở dạng ndt7 hiện nay, cố ý dùng một kết nối trong thời lượng cố định. Theo đặc tả giao thức, dữ liệu được truyền qua WebSocket. Việc chỉ dùng một kết nối là có chủ đích: mục tiêu là đo một luồng TCP đạt được bao nhiêu trên đường đó.
Không cách nào sai. Chúng trả lời hai câu hỏi khác nhau: "đường này tải được tổng cộng bao nhiêu?" so với "một kết nối nhận được bao nhiêu?". Một luồng có thể cho kết quả thấp trên đường rất nhanh; nhiều luồng lại có thể thổi phồng kết quả trên đường mà lưu lượng thực chủ yếu chỉ đi qua một kết nối.
Từ các mẫu thành một con số
Bài đo thu nhiều phép đo rồi phải rút gọn thành một con số chính. Lựa chọn này quan trọng:
| Cách tổng hợp | Ảnh hưởng |
|---|---|
| Trung bình mọi lần chạy | Bị kéo xuống bởi giai đoạn tăng tốc chậm và các trục trặc đơn lẻ |
| Trung vị | Chống nhiễu ngoại lai; con số ổn định, thận trọng |
| Lần chạy tốt nhất (hoặc phân vị cao) | Con số cao nhất, gần dung lượng đỉnh, ít điển hình nhất |
| Trung bình cắt đuôi (bỏ cao nhất và thấp nhất) | Thỏa hiệp giữa hai cách trên |
Cùng một đường truyền, cùng các mẫu thô, vẫn có thể hiện kết quả khác rõ rệt tùy công cụ chọn cách nào.
Độ trễ khi có tải
Độ trễ lúc rảnh và độ trễ khi đường truyền bận là hai phép đo khác nhau. Đường ping 15 ms khi yên tĩnh có thể vọt lên hàng trăm mili giây khi một lần truyền làm đầy bộ đệm. Bản thảo về độ phản hồi của nhóm làm việc IETF IPPM chuẩn hóa phép đo này, biểu thị bằng số vòng đi về mỗi phút. Hầu hết bài đo trên trình duyệt chỉ báo độ trễ lúc rảnh. Nếu độ trễ của bạn vọt lên khi có tải, xem bufferbloat được giải thích.
Jitter được tính ra, không quan sát trực tiếp
Không ai đo jitter trực tiếp. Bài đo gửi một chuỗi yêu cầu nhỏ, ghi độ trễ từng lần rồi suy ra jitter từ chuỗi đó. Các công cụ không thống nhất công thức: trung bình chênh lệch tuyệt đối giữa các mẫu liên tiếp, độ lệch chuẩn của mọi mẫu, hoặc ước lượng trượt có làm mượt như trong RFC 3550. Cùng dữ liệu cho ra các con số khác nhau, nên chỉ so sánh jitter giữa các lần chạy của cùng một công cụ. Về tác động của jitter đến cuộc gọi và trò chơi, xem jitter và mất gói tin.
Bài đo của BrowserInsight làm thế nào
Như một ví dụ cụ thể, đây là cách bài kiểm tra tốc độ của chúng tôi hoạt động, một thiết kế hợp lý trong nhiều lựa chọn:
- Truyền tải: yêu cầu HTTP tới điểm cuối biên của chính chúng tôi, mỗi lần một luồng (tuần tự, không song song).
- Khởi động: một yêu cầu khoảng 30 KB có kết quả bị bỏ trước các giai đoạn tải xuống và tải lên.
- Kích thước tải: khi tải xuống, các lần truyền tăng từ 200 KB lên 1 MB rồi 3 MB, sau đó điều chỉnh để mỗi lần truyền mất khoảng hai giây, tối đa 10 MB. Kích thước tải lên được nhân theo tốc độ của lần tải lên 200 KB đầu tiên.
- Thời lượng: giai đoạn tải xuống chạy cho đến khi đủ cả 15 giây và ít nhất ba lần truyền, dừng muộn nhất ở 30 giây hoặc mười lần truyền; giai đoạn tải lên thực hiện tối đa ba lần truyền.
- Tính giờ: mỗi lần truyền được tính từ lúc gửi yêu cầu đến khi byte cuối cùng tới (hoặc lần tải lên được xác nhận), nên mỗi mẫu đều bao gồm một vòng đi về.
- Thông lượng chính: trung vị của các lần truyền được tính giờ trong mỗi giai đoạn.
- Độ trễ: trung bình của ba yêu cầu HTTP 1 KB, sau một yêu cầu mồi bị bỏ.
- Jitter: trung bình chênh lệch tuyệt đối giữa các mẫu độ trễ liên tiếp.
Đánh đổi rất rõ: một luồng phản ánh một kết nối nhận được gì, nhưng có thể cho kết quả thấp hơn bài đo nhiều luồng trên đường rất nhanh. Chỉ có ba mẫu độ trễ cũng khiến con số jitter khá thô: hãy xem nó là chỉ báo nhanh, không phải kết luận về chất lượng cuộc gọi. Bài đo không dùng ICMP, không chạy nhiều luồng song song và không đo độ trễ khi có tải.
Danh sách kiểm tra khi đọc trang mô tả phương pháp
Trước khi tin một con số, hãy xem:
- Luồng: một kết nối hay nhiều?
- Thời lượng: thời gian cố định hay kích thước tệp cố định?
- Khởi động: giai đoạn tăng tốc có bị bỏ không, và bỏ thế nào?
- Tổng hợp: trung vị, trung bình hay lần chạy tốt nhất?
- Khoảng cách máy chủ: điểm cuối bài đo ở đâu so với bạn?
- Định nghĩa độ trễ: lúc rảnh hay có tải, HTTP hay ICMP?
Công cụ trả lời cởi mở những câu này hữu ích hơn công cụ có con số lớn hơn.
Câu hỏi thường gặp
Trang web có đo ping của tôi bằng ICMP được không?
Không. Trình duyệt không cho trang web dùng ICMP hay socket thô. "Ping" trên trình duyệt là thời gian một vòng HTTP hoặc WebSocket nhỏ đi về, gồm một ít thời gian xử lý của máy chủ.
Vì sao bài đo tải trước một tệp rồi bỏ đi?
Để vượt qua giai đoạn khởi đầu chậm của TCP. Kết nối mới bắt đầu với cửa sổ tắc nghẽn nhỏ nên các byte đầu chạy chậm. Lần truyền khởi động (hoặc bỏ khoảng đầu) giúp phép đo phản ánh thông lượng ổn định.
Bài đo một luồng kém chính xác hơn nhiều luồng?
Không kém chính xác, chỉ là trả lời câu hỏi khác. Một luồng đo một luồng TCP đạt được bao nhiêu; nhiều luồng đo tổng dung lượng đường truyền. Trên đường rất nhanh, bài đo một luồng có thể cho kết quả thấp hơn.
Vì sao độ trễ trên trình duyệt cao hơn ping dòng lệnh?
Độ trễ HTTP, ngoài vòng đi về của mạng, còn gồm xử lý của máy chủ và xử lý kết nối, trong khi ping ICMP chỉ đo phần mạng.
Kết luận
Bài đo tốc độ trên trình duyệt là một chuỗi lần truyền HTTP được tính giờ, và cách nó được thiết kế phụ thuộc vào những gì trang web được phép làm. Cách xử lý khởi động, kích thước tải, số luồng và cách tổng hợp quyết định con số chính nhiều hơn hầu hết mọi người nghĩ. Hãy đọc trang mô tả phương pháp với những điều này trong đầu, rồi chạy thử bài kiểm tra tốc độ mạng của chúng tôi, đối chiếu với thiết kế đã mô tả ở trên.
Đọc thêm:


