Blog

/

Frontend

React vs Vue | Next.js vs Nuxt

React vs Vue, Next.js vs Nuxt

Posted at

2024年10月10日

Posted on

Frontend

React vs Vue 都幾

雖然我是 React 的長年擁護者,覺得React Hook, React Query 很方便,不過還是來比較下區別。React 和 Vue 都是 CSR,瀏覽器下載 JavaScript,執行框架,再向伺服器要資料,最後才渲染。Vue 的語法直觀,看個簡單的計數器:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="count++">Increment</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<style scoped>
button {
  padding: 8px 16px;
}
</style>

state 就是 count,修改就是 count++。

React 做同樣的事:

import { useState } from 'react'

export default function Counter() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  )
}

其實用起來也不複雜,但需要理解 useState、Closure、不能直接改 count 要用 setCount,比較複雜一點。React 和 Vue 平常用起來差不多,不過前者 React Query 在自動快取、後台 refetch 等場景寫起來很簡單,是 Vue 的好幾倍。

框架對載入速度的實際影響

首頁、元件、API 的載入速度,不同框架有很大差異嗎?絕對是有的,但不是框架本身,而是渲染方式。假設要做一個產品列表頁,React SPA 的做法會是:

export default function Products() {
  const [products, setProducts] = useState([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    fetch('/api/products')
      .then(r => r.json())
      .then(data => {
        setProducts(data)
        setLoading(false)
      })
  }, [])

  return loading ? <p>Loading...</p> : <ProductList products={products} />
}

流程:用戶訪問 → 下載 HTML(空頁面)→ 下載 JavaScript → 執行 React → 發起 fetch → 等待 API 響應 → 渲染。首屏時間取決於 JS bundle 大小、執行時間、API 延遲,通常 2 到 3 秒。

但如果是 Next.js SSR 的做法呢?

async function getProducts() {
  const res = await fetch('https://api.example.com/products')
  return res.json()
}

export default async function Products() {
  const products = await getProducts()
  return <ProductList products={products} />
}

流程:用戶訪問 → 伺服器執行 getProducts(已經有資料)→ 伺服器渲染 HTML → 返回完整頁面。首屏時間只取決於伺服器的執行時間和網絡延遲,通常 0.5 到 1 秒。

Next.js ISR 的做法。

export const revalidate = 3600 // 每小時

export default async function Products() {
  const products = await getProducts()
  return <ProductList products={products} />
}

流程:用戶訪問 → 返回預先生成的 HTML(直接從 CDN)。首屏時間只是網絡延遲。通常 0.05 到 0.2 秒。

看起來 Next.js 和 Nuxt 快一倍以上,但這不是因為框架本身更快,而是因為改用了 SSR 或 ISR。React SPA 和 Vue SPA 用 SSR 或 ISR 時,速度完全一樣。

全棧框架:Next.js vs Nuxt

搞定了基礎框架,接下來考慮全棧。如果需要 SEO、首屏速度、或者伺服器端邏輯,單純的客戶端框架就不夠了。Next.js 是基於 React 的全棧框架,SSR、SSG、ISR 都支援,App Router 還引入了 Server Components。而 Nuxt 則是基於 Vue 的全棧框架,功能上和 Next.js 差不多,也支援 SSR、SSG、ISR,但社群相對小。

React + Express vs Next.js:代價對比

假設你有個消費者產品,需要登入、資料庫、複雜的後端邏輯。用 React 加自建 Express 伺服器,還是用 Next.js?



什麼情況用什麼

如果只是一個簡單的 Landing Page,用 React 或 Vue 都可以,完成後部署到 Netlify 或 Vercel 靜態託管,不用 Next.js 或 Nuxt。如果是面向消費者的產品可以用 Next.js 或 Nuxt。用 Next.js 的話,直接部署到 Vercel,省得自己維護伺服器。至於 Nuxt… 我真的蠻少聽到有大公司在用,Vue 會寫的本來就比 React 少,Nuxt 就更少了。

如果只有靜態內容,部落格或文檔,也可以考慮用 Astro。Astro 在靜態生成上是天花板,速度、開發體驗都更好。