Valibot vs Zod: Tuyệt chiêu ‘ép cân’ Bundle Size cho dự án TypeScript

Development tutorial - IT technology blog
Development tutorial - IT technology blog

Góc tối của Zod: Khi sự tiện lợi đi kèm với “cân nặng”

Trong cộng đồng TypeScript, Zod gần như là lựa chọn mặc định để validate dữ liệu. Cú pháp chainable như z.string().email() thực sự rất gây nghiện vì viết nhanh và dễ đọc. Thế nhưng, cái giá phải trả cho sự tiện lợi này thường nằm ở Bundle Size – thứ mà nhiều anh em dev chỉ nhận ra khi dự án đã phình to.

Câu chuyện bắt đầu khi mình refactor một dashboard quản trị khoảng 50K dòng code. Khi bật webpack-bundle-analyzer, mình thực sự sốc: Zod chiếm gần 50KB (gzipped). Nghịch lý ở chỗ, dự án chỉ dùng khoảng 10% tính năng của nó để kiểm tra string và object đơn giản. Do Zod không hỗ trợ Tree-shaking hiệu quả, dù bạn chỉ dùng một hàm duy nhất, trình duyệt vẫn phải tải về gần như toàn bộ thư viện.

Tại sao Zod lại khó tối ưu đến vậy?

Điểm yếu cốt lõi nằm ở kiến trúc Method Chaining. Để hỗ trợ kiểu viết z.string().email(), Zod phải định nghĩa tất cả phương thức bên trong một class hoặc object khổng lồ.

Các công cụ như Webpack hay Vite không thể bóc tách xem bạn có thực sự dùng .email() hay không. Hệ quả là người dùng phải gánh thêm code thừa, làm tăng chỉ số LCP (Largest Contentful Paint) và kéo dài thời gian thực thi JavaScript. Với các thiết bị di động cấu hình thấp, 50KB JavaScript không chỉ là con số, đó là sự chậm trễ có thể cảm nhận được.

Valibot: Tư duy Functional thay đổi cuộc chơi

Valibot giải bài toán này bằng cách tiếp cận Modular. Thay vì nhồi nhét mọi thứ vào một object, Valibot tách nhỏ các tính năng thành từng hàm riêng biệt. Bạn cần gì thì import nấy.

Cơ chế này cho phép Tree-shaking hoạt động tối đa công suất. Nếu bạn không dùng đến email() hay url(), chúng sẽ biến mất khỏi file build cuối cùng. Thực tế cho thấy, Valibot có thể nhỏ hơn Zod tới 90% (chỉ khoảng dưới 5KB gzipped cho các case thông thường). Đây là một con số cực kỳ ấn tượng.

Triển khai Valibot trong dự án thực tế

1. Cài đặt nhanh

Bạn có thể thêm Valibot vào dự án chỉ với một dòng lệnh:

npm install valibot
# Hoặc dùng pnpm/yarn
pnpm add valibot

2. Định nghĩa Schema: Sự khác biệt về tư duy

Hãy nhìn cách Valibot cấu trúc lại Schema để tối ưu dung lượng so với Zod.

Với Zod (Tất cả trong một):

import { z } from 'zod';

const UserSchema = z.object({
  username: z.string().min(3),
  email: z.string().email(),
});

Với Valibot (Dùng bao nhiêu, lấy bấy nhiêu):

import * as v from 'valibot';

const UserSchema = v.object({
  username: v.pipe(v.string(), v.minLength(3)),
  email: v.pipe(v.string(), v.email()),
  age: v.optional(v.number()),
});

Ở đây, v.pipe() đóng vai trò kết nối các điều kiện. Cách viết này nhìn qua có vẻ dài hơn một chút, nhưng chính nó là chìa khóa để trình đóng gói loại bỏ những đoạn code không dùng đến.

3. Parse dữ liệu và xử lý lỗi

Valibot cung cấp hai cách chính để kiểm tra dữ liệu, tùy thuộc vào cách bạn muốn xử lý logic.

const rawData = { username: "dev_viet", email: "[email protected]" };

// Cách 1: Dùng cho logic cần ném lỗi ngay lập tức
try {
  const data = v.parse(UserSchema, rawData);
} catch (err) {
  console.error(err);
}

// Cách 2: Safe parse (Khuyên dùng để code sạch hơn)
const result = v.safeParse(UserSchema, rawData);
if (result.success) {
  console.log("Data chuẩn:", result.output);
} else {
  console.log("Lỗi cụ thể:", result.issues);
}

Khi nào bạn nên thực sự chuyển sang Valibot?

Không nhất thiết phải đập đi xây lại mọi thứ nếu dự án của bạn đang chạy ổn. Tuy nhiên, hãy ưu tiên Valibot trong 2 kịch bản sau:

  • Ứng dụng Client-side thuần túy: Những trang Landing Page hoặc E-commerce ưu tiên tốc độ tải trang cực nhanh.
  • Phát triển Library/SDK: Đừng bắt người dùng thư viện của bạn phải gánh thêm 50KB từ Zod chỉ để validate vài tham số đầu vào.

Gần đây, mình đã thay thế Zod cho một module đăng ký. Kết quả? Bundle size giảm ngay 28KB. Với người dùng mạng 3G yếu, điều này giúp form hiển thị và tương tác nhanh hơn khoảng 200-300ms.

Lời kết

Valibot không chỉ là công cụ validation, nó đại diện cho xu hướng Modular hóa trong hệ sinh thái JavaScript hiện đại. Dù hệ sinh thái của nó chưa thể sánh bằng Zod về số lượng plugin, nhưng sự gọn nhẹ và hiệu suất là thứ không thể phủ nhận.

Nếu bạn đã quen với Zod, việc chuyển sang Valibot chỉ mất khoảng 15 phút làm quen. Hãy thử tối ưu dự án tiếp theo của mình, người dùng sẽ cảm ơn bạn vì điều đó.

Share: