blog.dopana

Back

Svelte là framework UI khác biệt: nó compile component thành JavaScript thuần ở build time, không gửi runtime framework cho browser.

React:    Component → JSX → React runtime → Virtual DOM → Real DOM
Svelte:   Component → Compiler → Vanilla JS → Real DOM (trực tiếp)
plaintext

Kết quả: bundle nhỏ hơn, nhanh hơn, không cần virtual DOM.

Tại Sao Svelte?#

Bundle Size#

# React + ReactDOM: ~40KB min+gzip
# Svelte: 0KB runtime (chỉ code bạn viết)
bash

App càng nhỏ, Svelte càng lợi thế. Một “Hello World” Svelte: ~2KB. React: ~40KB.

Performance#

Không virtual DOM = không diff, không reconciliation. Svelte biết chính xác DOM nào cần update khi state thay đổi — vì compiler tính trước.

React:  state change → diff VDOM → patch DOM
Svelte: state change → direct DOM update (compiler biết trước)
plaintext

Component#

HTML, script, style trong một file. Scoped CSS mặc định.

Reactivity#

Không useState, không useEffect, không dependency array. Gán biến = tự động reactive.

Props & Events#

<!-- Parent.svelte -->
<script>
  import Child from './Child.svelte'

  const items = [
    { id: 1, name: 'Svelte' },
    { id: 2, name: 'SvelteKit' },
  ]

  function onSelect(event) {
    console.log('Selected:', event.detail.item)
  }
</script>

<Child title="Frameworks" {items} on:select={onSelect} />
svelte

Logic Blocks#

Stores (State Management)#

// store.ts — Svelte store là observable
import { writable, derived } from 'svelte/store'

export const count = writable(0)
export const doubled = derived(count, ($count) => $count * 2)

// Methods
export function increment() {
  count.update(n => n + 1)
}
export function reset() {
  count.set(0)
}
svelte
<script>
  import { count, doubled, increment } from './store'

  // Auto-subscribe — reactive
  // $ prefix = tự động subscribe/unsubscribe
</script>

<p>Count: {$count}</p>
<p>Doubled: {$doubled}</p>
<button on:click={increment}>+</button>
svelte

Transitions & Animations#

CSS transitions native — không cần thư viện animation.

SvelteKit (App Framework)#

SvelteKit là Next.js của Svelte — fullstack framework:

npm create svelte@latest my-app
cd my-app
npm install
npm run dev
bash

Routing#

<!-- src/routes/+page.svelte — trang chủ -->
<h1>Home</h1>

<!-- src/routes/blog/[slug]/+page.svelte — dynamic route -->
<script>
  import { page } from '$app/stores'
  export let data  // Từ load function
</script>

<h1>{data.post.title}</h1>
<article>{@html data.post.content}</article>
svelte

Load Data#

// src/routes/blog/[slug]/+page.ts
export async function load({ params, fetch }) {
  const res = await fetch(`/api/posts/${params.slug}`)
  const post = await res.json()
  return { post }
}
typescript

Form Actions#

// src/routes/login/+page.server.ts
export const actions = {
  default: async ({ request }) => {
    const data = await request.formData()
    const email = data.get('email')
    const password = data.get('password')

    // Validate
    if (!email) return { error: 'Email required' }

    // Login logic
    const user = await login(email, password)
    return { success: true }
  }
}
typescript
<script>
  import { enhance } from '$app/forms'
  export let form  // Server trả về
</script>

<form method="POST" use:enhance>
  <input name="email" type="email">
  <input name="password" type="password">
  <button type="submit">Login</button>
</form>

{#if form?.error}
  <p class="error">{form.error}</p>
{/if}
svelte

Svelte vs React#

ReactSvelte
Runtime~40KB0KB (compiled)
Virtual DOM❌ (direct DOM)
StateuseState, useReducerlet, $:, stores
EffectuseEffect + deps$: reactive statements
Propsprops objectexport let
EventsCallback propscreateEventDispatcher
CSSCSS-in-JS, modulesScoped mặc định
TransitionReact Transition Group, FramerBuilt-in (fade, slide, fly)
Learning curveCao (JSX, hooks, deps)Thấp (HTML + JS)
BundleApp + React runtimeChỉ code của bạn

Khi nào dùng Svelte?#

✅ Nên dùng:

  • Web app nhỏ-gọn — bundle size quan trọng
  • Interactive UI — animation, transition nhiều
  • Team mới học — Svelte dễ hơn React
  • Embedded UI — bundle nhỏ = load nhanh

❌ Không nên:

  • Ecosystem dependency — React ecosystem lớn hơn
  • Team React chuyên — không cần đổi
  • Job market — React jobs nhiều hơn

Tổng Kết#

Svelte đơn giản hóa web development bằng cách compile đi complexity.

<!-- Svelte: code = HTML + JS, framework xử lý phần còn lại -->
<script>
  let count = 0
</script>

<button on:click={() => count++}>
  Clicked {count} {count === 1 ? 'time' : 'times'}
</button>

<style>
  button { background: purple; color: white; }
</style>
svelte
Tính năngSvelteReact
Bundle~2KB (Hello World)~40KB
Boilerplate0 (gán biến = state)useState, useEffect
Scoped CSSMặc địnhCSS-in-JS
AnimationBuilt-inThư viện
Compile time
Runtime0KB~40KB

Svelte không phải “React killer” — nó là alternative cho những ai muốn ít abstraction hơn, bundle nhỏ hơn, và code gần với HTML thuần hơn.

Tài liệu tham khảo#