Một nội dung chỉ có vài ký tự nhưng lại vượt giới hạn byte khi lưu hoặc gửi đi. Nếu kiểm tra bằng text.length, bạn có thể đang đo một đại lượng khác với thứ hệ thống giới hạn.
Bài đánh giá hai lựa chọn theo cùng tiêu chí: đơn vị đo, độ dễ dùng, phạm vi runtime, chi phí thao tác và tình huống phù hợp. Ví dụ đã chạy với Node.js 24.18.1, đối chiếu tài liệu ngày 31/10/2026. Không có benchmark tốc độ hay khẳng định một hàm nhanh hơn trên dữ liệu sản phẩm.
1. Hai con số trả lời hai câu hỏi
String.length đếm UTF‑16 code unit của chuỗi JavaScript. Buffer.byteLength(text, 'utf8') cho biết số byte khi mã hóa chuỗi đó bằng UTF‑8. Cả hai đều hữu ích khi yêu cầu dùng đúng đơn vị.
Một emoji có thể dùng hai code unit nhưng bốn byte UTF‑8. Một chữ tiếng Việt có dấu cũng có thể dùng nhiều byte dù chỉ chiếm một code unit. Vì vậy, không thể đổi qua lại bằng quy tắc nhân hai hoặc một hằng số áp dụng cho mọi nội dung.
import {Buffer} from 'node:buffer';
for (const text of ['abc', 'Việt', '🙂']) {
console.log(text, text.length, Buffer.byteLength(text, 'utf8'));
}
Chạy dưới dạng file .mjs. Fixture cho ba cặp số lần lượt là 3/3, 4/6 và 2/4. Chúng đủ chứng minh hai phép đo không tương đương, chưa đại diện tỷ lệ kích thước cho mọi chuỗi tiếng Việt.
2. So sánh trên cùng một yêu cầu
Về độ dễ bắt đầu, .length có ngay trên string, còn Buffer.byteLength cần môi trường có Buffer; ví dụ dùng import rõ ràng từ Node. Trên trình duyệt không có Buffer mặc định, không nên sao chép import Node vào bundle rồi coi đó là cấu hình hoàn chỉnh.
Về quyền kiểm soát, byteLength cho phép chỉ định encoding. Hãy ghi 'utf8' nếu giới hạn của bạn thực sự là UTF‑8. Chọn encoding khác để số nhỏ đi không giải quyết yêu cầu lưu trữ ban đầu.
Về chi phí, .length không thực hiện phép mã hóa UTF‑8 trong đoạn gọi đó. ByteLength cần xác định kích thước theo encoding; không tạo sẵn cả Buffer chỉ để đọc .length khi chỉ cần số byte. Bài không đo thời gian, cấp phát hoặc bộ nhớ để xếp hạng hiệu năng hai cách.
Về chi phí vận hành và hệ sinh thái, cả hai đều có sẵn trong runtime được dùng ở đây, không cần dịch vụ tính phí hay dependency ngoài. Tuy vậy, giới hạn được cấu hình ở database, file hoặc giao thức vẫn phải đọc riêng; không phải trường nào ghi “length” cũng có cùng đơn vị.
3. Đo đúng dữ liệu sau serialize
Nếu thứ được ghi là JSON, hãy đo chuỗi JSON đã serialize. Dấu ngoặc, tên thuộc tính và ký tự escape cũng thuộc nội dung đó. Đo riêng một trường trước serialize dễ đánh giá thiếu kích thước.
import {Buffer} from 'node:buffer';
import assert from 'node:assert/strict';
const value = {message: 'Việt🙂'};
const serialized = JSON.stringify(value);
const bytes = Buffer.byteLength(serialized, 'utf8');
assert.equal(bytes, Buffer.from(serialized, 'utf8').length);
assert.ok(bytes > Buffer.byteLength(value.message, 'utf8'));
console.log(serialized, bytes);
Assertions đã chạy thành công trên Node nêu trên. Đây là kích thước UTF‑8 của chuỗi JSON, chưa gồm metadata, nén, mã hóa hoặc lớp bao của nơi nhận. Nếu dữ liệu còn biến đổi sau đó, đo ở đúng ranh giới của giới hạn cần thực thi.
4. Giới hạn ký tự hiển thị là yêu cầu khác
Nếu sản phẩm muốn giới hạn “ký tự người dùng nhìn thấy”, cả hai phép đo có thể chưa đúng. Một biểu tượng hoặc chữ ghép có thể gồm nhiều code point. Intl.Segmenter với granularity grapheme là một công cụ phù hợp để nghiên cứu yêu cầu đó.
const text = 'e\u0301';
const segmenter = new Intl.Segmenter('vi', {granularity: 'grapheme'});
console.log(text.length, [...text].length, [...segmenter.segment(text)].length);
Fixture này đã cho 2, 2, 1 trên Node 24.18.1. Kết quả minh họa một chữ có dấu kết hợp; không thay thế kiểm tra các emoji hoặc bộ chữ nằm trong phạm vi sản phẩm. Cũng không tự chuẩn hóa nội dung chỉ để ép mọi phép đếm bằng nhau.
Chọn phép đo và kiểm tra lại
Ghi đơn vị vào tên biến như utf8Bytes hoặc codeUnits giúp reviewer phát hiện nhầm lẫn. Với giới hạn byte, thử ASCII, tiếng Việt, emoji và chuỗi chứa dấu xuống dòng sau serialize. Với giới hạn giao diện, kiểm tra riêng quy tắc grapheme và khả năng hỗ trợ runtime.
Chọn .length cho yêu cầu dựa trên code unit, chọn byteLength cho kích thước theo encoding. Quyết định đến từ hợp đồng dữ liệu và vị trí đo; bảng số nhỏ trong bài là cách kiểm tra quyết định đó, không phải bảng xếp hạng công cụ.


