Bỏ qua điều hướng

Svelte là gì? Framework JavaScript hoạt động như một compiler

Svelte là framework compiler-first, tối ưu hiệu suất bằng cách chuyển công việc từ runtime sang build step, loại bỏ Virtual DOM và giảm JavaScript payload.

Tuan Tran Van
10 phút đọc
Mục lục (10 phần)
  1. Svelte là gì?
  2. Vì sao Svelte được gọi là framework compiler-first?
  3. Compiler của Svelte làm gì khi bạn build?
  4. Virtual DOM: vì sao Svelte bỏ hẳn cơ chế này?
  5. Runes: cách Svelte 5 quản lý trạng thái phản ứng
  6. Single-File Component: template, script và style trong một file
  7. SvelteKit: từ component đến ứng dụng hoàn chỉnh
  8. Svelte khác React ở điểm nào?
  9. Khi nào nên chọn Svelte cho dự án của bạn?
  10. Tài liệu tham khảo

Svelte là một framework JavaScript dùng để xây dựng giao diện người dùng dựa trên triết lý biên dịch (compiler-first).

Khác với các framework truyền thống so sánh trạng thái (diffing) ngay trong trình duyệt, Svelte chuyển đổi mã nguồn khai báo thành các chỉ dẫn JavaScript thao tác trực tiếp với DOM (Document Object Model) ngay tại bước xây dựng (build step).

Cách tiếp cận này loại bỏ phần lớn các lớp trừu tượng trung gian và bộ máy thực thi (runtime) cồng kềnh thường thấy.

Kết quả là ứng dụng cuối có kích thước bundle tối giản, tốc độ thực thi tiệm cận JavaScript thuần và giảm thiểu đáng kể chi phí tính toán trên thiết bị người dùng.

Mã nguồn khai báo đi qua compiler của Svelte và đi ra thành JavaScript thuần tinh gọn

Svelte là gì?

Svelte là một công cụ viết các thành phần giao diện (UI components) — như navigation bar, form hoặc dashboard — để chạy trên trình duyệt. Thay vì gửi một thư viện nặng hàng chục KB xuống máy người dùng (client) để quản lý giao diện, Svelte hoạt động như một trình biên dịch, phân tích mã nguồn và dán trực tiếp các logic cập nhật vào kết quả đầu ra.

Về mặt ứng dụng, Svelte đủ linh hoạt để làm một thư viện tạo web component đơn lẻ hoặc làm nền tảng cho các hệ thống full-stack quy mô lớn. Nó cung cấp đủ các khối cơ bản cần thiết: quản lý trạng thái, scoped CSS, và các hiệu ứng chuyển cảnh (transitions) mà không đòi hỏi các thư viện bổ trợ phức tạp.

Vì sao Svelte được gọi là framework compiler-first?

Triết lý "compiler-first" của Svelte thay đổi hoàn toàn kiến trúc truyền tải mã nguồn. Trong mô hình của React hay Vue, trình duyệt phải tải về một "reactivity engine" hoặc bộ hòa giải (reconciler) để tính toán sự thay đổi giữa các trạng thái. Svelte đẩy hầu hết các công việc phân tích này về bước biên dịch.

So sánh hai cách phân phối mã: framework runtime-first gửi cả bộ máy xuống trình duyệt, còn Svelte biên dịch trước nên framework gần như biến mất khỏi bundle

Sau khi quá trình build hoàn tất, framework gần như "biến mất". Bundle (gói mã cuối cùng) gửi đến người dùng không chứa bộ máy quản lý framework mà chỉ bao gồm các hàm JavaScript tinh gọn, cập nhật DOM dựa trên các biến cụ thể đã được xác định từ trước.

Cơ chế này giảm mạnh JavaScript payload và bỏ bớt các lớp trừu tượng trung gian giữa logic code và DOM. Điều này đặc biệt quan trọng khi tối ưu Time-to-Interactive (TTI — thời gian đến lúc trang thật sự bấm được), vì trình duyệt không cần tiêu tốn chu kỳ CPU để khởi tạo và chạy các logic nội tại của framework trước khi hiển thị nội dung.

Compiler của Svelte làm gì khi bạn build?

Compiler của Svelte không gộp file: nó phân tích tĩnh (static analysis) mã nguồn ở mức sâu. Trước tiên, nó tách file .svelte thành ba bucket: logic (script), cấu trúc (visual tags), và định dạng (style).

Quy trình biên dịch: một file .svelte tách thành ba phần script, markup và style, được phân tích thành AST rồi sinh ra các chỉ dẫn cập nhật DOM trực tiếp

Hệ thống sử dụng các bộ parser chuyên dụng như acorn để phân tích cây cú pháp trừu tượng (Abstract Syntax Tree - AST) của JavaScript và css-tree cho định dạng. Việc phân tích AST cho phép Svelte biết chính xác node nào có khả năng thay đổi dữ liệu (reactive nodes), từ đó tạo ra mã mệnh lệnh (imperative) tối ưu. Đối với CSS, compiler tự động thêm tiền tố (scoped prefix) vào các selector để cô lập style, ngăn xung đột CSS toàn cục mà không cần runtime library như các giải pháp CSS-in-JS.

Kết quả cuối cùng là compiler chuyển đổi markup HTML thành các chỉ dẫn DOM trực tiếp (imperative DOM instructions). Thay vì render lại cả cây, nó chỉ "dán" đúng mã lệnh cần thiết để cập nhật node bị ảnh hưởng.

Ví dụ về cấu trúc mã JavaScript do compiler tạo ra (minh họa logic lifecycle):

javascript
// Cấu trúc mô phỏng mã biên dịch
export default function Component({ target, props }) {
  let { name } = props;
  let h1, textNode;
 
  return {
    create() {
      h1 = document.createElement("h1");
      textNode = document.createTextNode(name);
      h1.append(document.createTextNode("Hello "), textNode);
    },
    mount() {
      target.append(h1);
    },
    update(changes) {
      // Static analysis giúp compiler biết chính xác node cần cập nhật
      if (changes.name) {
        textNode.data = name = changes.name;
      }
    },
    detach() {
      h1.remove();
    },
  };
}

Virtual DOM: vì sao Svelte bỏ hẳn cơ chế này?

Svelte coi Virtual DOM là "chi phí bổ sung thuần túy" (pure overhead). Trong các hệ thống dùng Virtual DOM, trình duyệt phải thực hiện bước "Diffing" — so sánh hai bản sao của Virtual DOM để tìm ra sự khác biệt. Quá trình này ngốn tài nguyên CPU theo độ phức tạp của component tree, ngay cả khi chỉ có một biến nhỏ thay đổi.

Virtual DOM dựng bản sao rồi so sánh để tìm khác biệt, còn Targeted Updates gán thẳng giá trị mới vào node bị ảnh hưởng

Svelte loại bỏ hoàn toàn bước Diffing ở runtime. Nhờ trình biên dịch, framework đã biết rõ giá trị nào có thể thay đổi ngay từ lúc build. Thay vào đó, nó áp dụng "Targeted Updates" (Cập nhật có mục tiêu).

Thay vì chạy vòng lặp so sánh để đoán xem cái gì đã đổi, mã do Svelte tạo ra thực hiện các lệnh gán trực tiếp vào thuộc tính của node. Cơ chế này đi tắt qua các lớp kiểm tra trung gian, giúp ứng dụng phản hồi nhanh hơn và giải phóng tài nguyên CPU cho các tác vụ quan trọng khác của người dùng.

Runes: cách Svelte 5 quản lý trạng thái phản ứng

Svelte 5 giới thiệu "Runes" — các ký hiệu hướng dẫn compiler ($state, $derived, $effect) để quản lý tính phản ứng một cách tường minh hơn. Việc sử dụng cú pháp Rune giúp Svelte 5 hỗ trợ TypeScript tốt hơn và cho phép logic phản ứng hoạt động đồng nhất cả bên trong lẫn bên ngoài file .svelte.

Ba rune $state, $derived và $effect tạo thành đồ thị phụ thuộc, một giá trị thay đổi chỉ lan tới đúng những chỗ phụ thuộc vào nó

Dưới lớp vỏ của Runes là cơ chế phản ứng dựa trên Signal (Signal-based reactivity). Đây là hệ thống quản lý trạng thái ở mức độ "fine-grained" (hạt mịn). Khác với các cơ chế cũ thường làm vô hiệu hóa (invalidate) cả một danh sách hoặc component, Signals cho phép cập nhật chính xác đến từng node văn bản hoặc thuộc tính phần tử bị ảnh hưởng.

Ví dụ về logic phản ứng fine-grained với Runes:

svelte
<script>
  let count = $state(0);
  let doubled = $derived(count * 2); // Tự động tracking dependency
 
  $effect(() => {
    // Chỉ chạy khi 'count' thay đổi thực sự
    console.log(`Log: ${count}`);
  });
</script>
 
<button onclick={() => count++}>Count: {count} (X2: {doubled})</button>

Single-File Component: template, script và style trong một file

Cấu trúc Single-File Component (SFC) của Svelte đóng gói logic, cấu trúc và định dạng vào một file duy nhất. Điểm mạnh rõ nhất của SFC trong Svelte là Scoped CSS mặc định. Trình biên dịch sẽ tự động băm (hash) các class name, đảm bảo style của component này không "rò rỉ" sang component khác.

Cấu trúc một file .svelte gồm ba khối script, markup và style, với style được compiler cô lập bằng class băm

Cú pháp Svelte gần với HTML/JavaScript tiêu chuẩn, giúp giảm bớt mã boilerplate (mã khuôn mẫu lặp lại) và logic quản lý trạng thái thủ công. Sự tinh giản này giúp kỹ sư tập trung vào logic nghiệp vụ thay vì phải xử lý các ràng buộc đặc thù của framework.

Ví dụ Counter Component (Svelte 5):

svelte
<script>
  let count = $state(0);
</script>
 
<button onclick={() => count++}>
  Số lần nhấn: {count}
</button>
 
<style>
  button {
    color: #ff3e00;
    padding: 0.5rem 1rem;
  }
</style>

SvelteKit: từ component đến ứng dụng hoàn chỉnh

Nếu Svelte là đơn vị cấu thành, SvelteKit là meta-framework (framework dựng trên Svelte) cung cấp hạ tầng để chạy ứng dụng. SvelteKit xử lý định tuyến dựa trên file (file-based routing), server-side rendering (SSR), và đặc biệt là cơ chế Form Actions hỗ trợ Progressive Enhancement — giúp ứng dụng vẫn hoạt động cơ bản ngay cả khi JavaScript bị tắt hoặc chưa tải xong.

SvelteKit bọc quanh component Svelte và bổ sung file-based routing, server-side rendering, form actions và adapters

Trong các bản cập nhật SvelteKit 3 (hiện ở giai đoạn preview @next), framework giới thiệu nhiều cải tiến thực dụng như:

  • Shallow routing: Tích hợp trực tiếp vào hàm goto, cho phép thay đổi URL mà không cần tải lại dữ liệu hoặc re-render component.
  • Cơ chế refreshAll: Thay thế cho invalidateAll để đồng bộ trạng thái dữ liệu tường minh hơn.
  • $app/manifest: Cho phép can thiệp sâu vào cấu trúc build để tối ưu hóa việc phân phối tài nguyên.

Svelte khác React ở điểm nào?

Sự khác biệt lớn nhất nằm ở điểm cân bằng giữa hiệu suất thực thi và sự ổn định của hệ sinh thái.

Svelte và React đặt cạnh nhau trên bốn trục: kiến trúc, kích thước bundle, cách quản lý trạng thái và hệ sinh thái

  • Kiến trúc: Svelte là Compile-time (biên dịch mã), React là Runtime (xử lý khi chạy).
  • Bundle size: Svelte (2-5KB) so với React + ReactDOM (~42KB gzipped).
  • Tính dự đoán: React có lợi thế về tính dự đoán trong các cây component cực sâu nhờ bộ Reconciler đồng nhất. Svelte có lợi thế ở hiệu suất thô (raw performance) và kích thước tệp tin.
  • Quản lý trạng thái: Svelte dùng Runes (Signals) tự động theo dõi phụ thuộc, React dùng Hooks với các mảng phụ thuộc (dependency arrays) đòi hỏi kỷ luật lập trình cao để tránh bug.
  • Hệ sinh thái: React chiếm ưu thế rõ rệt về số lượng thư viện UI và thị trường việc làm. Svelte đang tăng trưởng nhanh nhưng vẫn là lựa chọn thiểu số trong phân khúc doanh nghiệp lớn.

Khi nào nên chọn Svelte cho dự án của bạn?

Svelte là lựa chọn tốt cho các dashboard nhạy cảm với độ trễ, các trang marketing cần bundle size nhỏ để tối ưu SEO, hoặc ứng dụng chạy trên thiết bị cấu hình yếu (IoT, Mobile Web). Nó phù hợp với các đội ngũ nhỏ muốn di chuyển nhanh mà không muốn bị sa lầy vào mã khuôn mẫu.

Tuy nhiên, bạn cần cân nhắc nếu dự án yêu cầu những component doanh nghiệp đặc thù (như biểu đồ tài chính phức tạp, data grid riêng) vốn đã được tối ưu tốt cho React. Ngoài ra, nếu lộ trình sản phẩm yêu cầu một ứng dụng di động native thực thụ, hệ sinh thái React Native vẫn là một lợi thế rõ rệt. Việc lựa chọn vẫn cần dựa trên đánh giá kỹ lưỡng về các đánh đổi (trade-off) trong hệ sinh thái.

Tài liệu tham khảo

Chia sẻ bài viết

X / TwitterFacebookLinkedIn