Heidi-Liu
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    3
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # 【學習筆記】談談 Next.js:基於 React 的 SSR 框架 [![hackmd-github-sync-badge](https://hackmd.io/SocrtbLTTe6ZDO-Ej4H3QQ/badge)](https://hackmd.io/SocrtbLTTe6ZDO-Ej4H3QQ) ![image](https://hackmd.io/_uploads/SkvRg5cd6.png) [toc] ## 前言 在認識 Next.js 之前,建議先複習 React 的相關知識,可參考過去的[《[week 21] 初探 React:Component、JSX 語法、props 與 state 的不同》](https://heidiliu2020.github.io/react-jsx-props/)系列筆記。 距離上次碰 React 感覺已經是好久以前的事情了,趁著這次組內專案需求,預計導入 Next.js 框架技術,寫下這篇學習筆記做記錄。 ## 初探 Next.js ### React vs Next.js:函式庫與框架 眾所周知,React 其實並不是框架(Framework),而是用來建構使用者介面的 JavaScript 函式庫(Library)。 而 Next.js 則是建立 React 之上的框架,除了客戶端渲染(Client-side Rendering),還支援兩種形式的預渲染:靜態網頁生成(Static Site Generation)和伺服器端渲染(Server-side Rendering)。 可參考官網的標語介紹: + [React](https://react.dev/):用於打造使用者介面的函式庫(The **library** for web and native user interfaces) + 此外官方也提到:「建議使用者使用全端 React 框架,如 Next.js 或 [Remix](https://remix.run/),以處理專案中的路由與資料處理等需求」 + [Next.js](https://nextjs.org/):用於網頁開發的 React 框架(The React **Framework** for the Web) ## 為何選擇 Next.js? 在使用任何新技術之前,都要先問為什麼會做出這個選擇,是否有解決實作上面臨的問題 ~~(畢竟面試也很常會被問到)~~,先瞭解前因後果,也有助於掌握各種工具的使用時機。 這裡我們可以從 React 提供的功能作為切入點,React 是由 [Facebook](https://github.com/facebook/react) 團隊所維護的 JavaScript 函式庫。 Angular、React、Vue,也就是俗稱的前端三大「框架」,常用於快速開發單頁式應用程式(Single Page Application,SPA),可達到前後端分離,以及提升使用者體驗等目的,例如 Gmail、Facebook 和 Netflix 等平台。 然而,由於 SPA 是利用客戶端渲染(CSR)技術,由 JavaScript 動態產生內容,若檢視原始碼會發現無法看到新增的內容,這將導致 SEO(搜尋引擎最佳化)較差的問題;也因為初次載入頁面需下載大量的 JavaScript 檔案,使第一次渲染較為費時,反而降低使用者體驗。 那該怎麼辦呢? 只要第一個畫面改由伺服器端渲染(SSR),即可解決 SEO 問題,其他畫面仍維持使用者端渲染(CSR),減少伺服器運算負荷,如此不就能夠兩者兼得了嗎? React 可透過「搭建後端 Server + 處理 Hydration + Webpack 打包配置」等設定來實現 SSR,但相對來說門檻較高,需耗費較多成本學習。 於是前端 SSR 框架就誕生了,如 React 的 [Next.js](https://nextjs.org/) 和 [Gatsby.js](https://www.gatsbyjs.com/),以及 Vue 的 [Nuxt.js](https://nuxt.com/)。 【延伸閱讀】關於 MVC、SPA 到 SSR 詳細演進,可閱讀 Huli 寫的這兩篇文章:[《跟著小明一起搞懂技術名詞:MVC、SPA 與SSR》](https://life.huli.tw/2018/05/04/introduction-mvc-spa-and-ssr-545c941669e9/)以及[《從歷史的角度探討多種 SSR(Server-side rendering)》](https://blog.huli.tw/2023/11/27/server-side-rendering-ssr-and-isomorphic/),前者明明是兩年前才讀過的文章,現在又有一層新的體悟。 ### Next.js 特別在哪? ![image](https://hackmd.io/_uploads/r1anuqcu6.png) 由 [Vercel](https://github.com/vercel/next.js) 團隊創建的 Next.js,解決了上述幾點網頁開發遇到的問題,以下是官網提及有關 Next.js v14(發布於 2023 年 12 月)的幾項特點: + Data Fetching:可控制資料載入的時機點 + CSS Support:內建支援 CSS、Sass 檔案,並支援 CSS 模組化 + Route Handlers:基於檔案架構的路由系統,如 `page/home.tsx` + API Routes:支援 API 路由,易於建立與管理 API 端點 + Pre-rendering:支援兩種形式的預渲染,分別是靜態網頁生成(SSG)和伺服器渲染(SSR) + Built-in Optimizations:針對圖片、字體、JavaScript 載入進行自動優化,包括延遲載入與緩存處理 綜合上述優點,Next.js 有助於優化網頁效能與 SEO,適合用於建立著陸頁面(Landing Page)或是產品展示頁面,但較不適合應用在經常變動的網站,避免伺服器負荷過大。 而 Next.js 實際使用案例可參考 [Showcase](https://nextjs.org/showcase) 頁面,如 Notion、Tik Tok 以及 Twitch 等網站。 ## 比較:CSR vs SSR vs SSG vs ISR ![image](https://hackmd.io/_uploads/Sk0QYQzYa.png) > Ref: [Next.js: The Ultimate Cheat Sheet To Page Rendering](https://dev.to/guydumais/next-js-the-ultimate-cheat-sheet-to-page-rendering-55eb) 最後針對 Next.js 支援的網頁渲染方式,以及如何在 Next.js 搭配使用,列點整理如下: + Client-side Rendering(CSR):客戶端渲染 + Client(瀏覽器)第一次發送 Request 給 Server => Server 回傳只有容器不含內容的 HTML 檔 => 再由瀏覽器執行 JavaScript 動態產生資料 => 最後將資料渲染到畫面上 + 因此第一次渲染較為費時,而只有容器沒有內容的原始碼也將不利於 SEO + 執行函數:`useEffect()` 或使用由 Next.js 團隊開發的 [SWR](https://swr.vercel.app/) 開源 套件 + Server-side Rendering(SSR):伺服器端渲染 + Server(伺服器)在每次收到 Request 時,會建立好完整的 HTML 內容並發送給 Client + 適用於需經常更新數據的頁面,缺點是可能導致伺服器負荷較大 + 執行函數:`getServerSideProps()`,只會在 Server side 執行,可跳過呼叫 API 步驟直接到資料庫抓取資料 + Static Site Generation(SSG):靜態網站生成 + 在網頁打包(built time)時,就由 Server 產生所有需要用到的內容,因此每次 Server 收到 Request 均回傳相同的 HTML 給 Client + 因 HTML 內容不變可搭配快取機制,適用於資料變動較小的頁面,無法動態更新 + 執行函數:`getStaticProps()` + Incremental Site Rendering(ISR):增量式網站渲染 + 結合 SSG 和 SSR 的渲染方式,可設定條件保存上一次渲染結果,當靜態檔案過期,將觸發 Server 重新 build HTML 檔案以更新頁面 + 執行函數: `getStaticProps()` 搭配 `revalidate` 屬性 也可參考 web.dev 這篇文章[《Rendering on the Web》](https://web.dev/articles/rendering-on-the-web?hl=zh-tw) 提供的表格整理: ![image](https://hackmd.io/_uploads/SyQLDXGKp.png) ## 結語 在實際瞭解 Next.js 這套框架之前,在社群或其他平台略有耳聞,透過這次學習,除了把 React 的基礎,也把過去常被問到的 MVC、SPA、CSR、SSR 等專有名詞再重新複習一遍。 不管選擇什麼技術或框架,重要的是為何要使用,又想解決什麼問題,不外乎結果都是為了提升使用者體驗,畢竟科技始終源自於人性。這篇只提及基本觀念,再來就是實際動手操作啦! ## 參考資料 + [18. [FE] 為什麼網站要做成SPA?SSR 的優點是什麼?](https://ithelp.ithome.com.tw/articles/10224772) + [深入淺出,完整認識Next.js 13 - iT 邦幫忙](https://ithelp.ithome.com.tw/users/20161853/ironman/6122) + [快速了解Next.js中的網頁渲染技術重點: SSR、SSG、ISR與CSR](https://hackmd.io/@pericode/HyRJHvAsj)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully