React.Js 框架比較:NextJs vs Remix

前言

NextJs 已經是 React.Js 生態裡相當知名的框架,提到 SSR 幾乎都會直接想到他
Remix名氣就沒這麼大了,為何突然在2022年逐漸進入大家的眼裡呢?

因為他開源了!
而 Remix 主打盡可能的使用 Browser API 以達到高效、輕量的框架
以下簡單做個對比,對於新專案框架選型時,可以有個簡單的快速參考

主要差異

Remix比較大的特點是

  1. 盡可能的使用原生 API,不允許 JavaScript 時,網站仍可運作。允許執行 JavaScript 時,則會有更佳的使用體驗
  2. 提交表單時,若有JavaScript,則會使用 XHR;若無,則使用原生的方式 submit(即發出 HTTP POST 請求)
  3. Remix 目前沒有提供靜態頁面產生(SSG, Static Site Generator)

ROUTE

兩個都是file-base routing system,也就是只要將js或ts檔放在指定目錄下,就會自動產出對應路由
主要在動態路由的檔案命名不同

Next.Js

pages/index.js ==> /  <-- 主頁面
pages/users/index.js ==> /users <-- USER頁面  
pages/users/[userid].js ==> /users/:userid <-- 動態路由,由網址取得參數
pages/

Remix

routes/index.js ==> /  <-- 主頁面
routes/users/index.js ==> /users <-- USER頁面  
routes/users/$userid.js ==> /users/:userid <-- 動態路由,由網址取得參數

比較特別的是,在深層路由時,Remix可以在檔名使用.來分離
而nextjs則是透過深層目錄來產生相應路由

routes/blog.news.js ==> /blog/news

(2024/02/22更新)
Remix V2,以 flat routes 為主。可以一目了然看清楚所有路由

routes/user._index.ts ==> /user
routes/user.$id.ts ==> /user/:id
routes/user.$id.edit.ts ==> /user/:id/edit

SSR資料載入

Next.Js

Page Router 你可以自行控制資料載入的時機點,如下

  • 執行期(runtime) Server-side + Client-side: getInitialProps (deprecated,會使next優化效果不彰)
  • 編譯期(build time)且僅Server-side: getStaticProps
  • 執行期(runtime)且僅Server-side: getServerSidePropsReact Server Components
  • 僅Client-side

範例

import fs from 'fs';
import path from 'path'

export async function getServerSideProps(context) {
    // 此處的程式碼僅會在Server side執行,故可以使用Node.Js原生語法如fs
    // 而next打包時會自動判斷不將其打包至前端
    const DUMMY =await fs.readFile(path.join(process.cwd(), 'TEST_DATA', 'DUMMY_DATA.json'))
  return {
    props: { data: DUMMY }, // 回傳時一律為內含props的object,此參數會被傳入React.Js裡
  }
}

export default function Home(props) {  
    const { data } = props;
    return (  
        <div>{data}</div>  
    );  
}

App Router 則直接寫在RSC(React Server Component)裡
相比 Page Router 更加簡單,不過 cache 機制需要花費不小心力去理解

Remix

Remix僅提供以下2種

  • 執行期(runtime) Server-side
  • 執行期(runtime) client-side
    import { useLoaderData } from 'remix';
      
    export let loader = async ({ params, request }) => {  
        // 由網址取得id,
        const id = params.id;
        // 由網址的 query string取得資料
        const url = new URL(request.url);
        const name = url.searchParams.get('name');  
        return { id, name };
    };  
      
    export default function Home() {  
        const { id, name } = useLoaderData();  
        return (  
            <div>  
                <h1>網址參數: {id}</h1>  
                <h1>query string欄位: {name}</h1>  
            </div>  
        );  
    }

Sessions和cookies

Next.Js

框架本身沒提供相關函式,但可以使用套件,如NextAuth.js來輔助

Remix

框架本身即提供相關函式可以使用

import { createCookie } from 'remix';

const cookie = createCookie('cookie-name', {
  expires: new Date(Date.now() + 60),
  httpOnly: true,
  maxAge: 60,
  path: '/',
  secrets: ['mysecret'],
  secure: true
});

比較表(2023/07/23增加)

正巧公司新專案技術選型,整理了比較表供參考

Nextjs (GitHub ⭐️: 109k) remix (GitHub ⭐️:24.1k)
支援 Vercel shopify
時間 2016/10/25 2021/11/22(開源)。本質是 react-router。可追遡到 2014 年
類型 全端框架。自帶後端可寫陽春api,可作為 middleware 層 同左
route file base routing system
也就是只要將js或ts檔放在指定目錄下,就會自動產出對應路由
同左
render SSR, SSG, ISR, RSC(React Server Component) SSR
seo 不常更新的頁面盡可能以靜態處理
偶爾更新則透過revalidate等觸發更新
新釋出的RSC縮短部份API時間
SSR
框架主打盡可能的使用原生 API
不允許 JavaScript 時,網站仍可運作。
允許執行 JavaScript 時,則會有更佳的使用體驗
form 同React開發。由js處理submit 支援原生form寫法
效能 優。網路上多篇比較文章(相同功能, 或著嘗試各種慢速情境)均表示載入速度remix > next
cookie App Router 僅提供 cookie
若頁面使用Page Router,則無。須依靠三方套件
框架提供cookie, session
原生css 提供module.css, style-jsx寫法。尤其style-jsx寫法可scope亦能打包出css檔以利cache 須透過LinkFunction載入實體css檔。要自行處理css命名衝突問題
圖片優化 原生提供 不提供
打包時間 依資料量變長 不受資料量影響,打包速度快
優點 1. 出現時間久
2. 周邊生態圈相對多
3. 網路資訊豐富
4. 有圖片優化功能
1. 載入速度快。框架本身底層優化強
2. 官方聲稱盡可能平滑過渡版本。不會有強烈的breaking change
3. 一律 SSR。心智負擔相對小
缺點 1. 大更新常伴有breaking change。如最近的App Router
2. 載入速度略輸remix
3. Next13的’use server’, ‘use client’ 周邊生態尚未跟上。實務開發大部份仍是’use client’居多
4. 須自行考量 SSG, SSR, RSC 使用時機
1. 年輕框架,可能有坑
2. 目前尚不支援RSC,但官方有在觀注React官方動態 (影響不大,因其SSR就完勝next RSC)
3. 生態可能相對少。但仍可使用React本身豐富的eco-system
4. 無圖片優化功能

後記

想追求效能極緻,可以試試新開源的Remix,畢竟是2021年尾才開源
目前 production 應用的網站算少
使用上遇到問題時可能會查不太到解法或著須至官方提 issue 詢問

不想要太過冒險,則推薦繼續使用已經成熟穩健的的 Next.Js
可以產生靜態頁面真的是最大優勢!

對於個人 Side Project,靜態頁面可以佈署在 netlify 或 GitHub page
上線後的營運成本絕對是最低的0元!

但仍可以關注 Remix 資訊,也許未來提供了靜態頁面產生
想必對於 Next.Js 目前已穩固的地位來說,將是一大挑戰!

參考資料

Next.js vs. Remix: Analyzing Key Aspects and Differences
Remix vs. Next.js: A Detailed Comparison