Next.js 入門

更新於 2022/05/03閱讀時間約 9 分鐘
React/Vue等框架預設都是CSR(Client-Side-Rendering),也就是畫面上任何元素的呈現,都是透過js去向後端拿資料後渲染在畫面上。因此,無論是SPA或MPA在該頁面的第一次載入會需要執行大量的js,速度會比較慢,但是之後的互動就會快很多,因為每次都是更動小區塊的畫面,使用者體驗很好。
然而,也因為CSR的特性,在SEO方面通常會較差,雖然Google爬蟲號稱可以爬取CSR渲染後的HTML,但可能還需要時間驗證效果如何。
因此,為了解決SEO問題,傳統的SSR(Server-Side-Rendering)又被拿出來討論了(現在講的SSR通常是指前端框架的SSR),許多大型專案紛紛開始採用SSR技術,如Next.js就是React的SSR框架,使用者透過瀏覽器進入某個頁面後,由Server產生完整的HTML並回傳瀏覽器,解決了第一次載入速度慢的問題,最重要的是解決了SEO問題。

安裝設置:

$ npx create-next-app@latest
安裝完成後,專案目錄結構如下:
執行$ npm run dev 可直接透過http://localhost:3000進入首頁,對應到pages/index.js。
#開發模式下啟動 Next.js 專案
$ npm run dev
Prod記得每次要先build再start:
#build next prod application
$ npm run build
#啟動next prod server
$ npm run start

接著看看它的source code,可以看到body中的html內容是完整的:
反之,CSR source code 只有root div,html內容皆是透過渲染產生的。

接著在pages下新增一個about.js,該頁面對應到http://localhost:3000/about,Next幫我們把Routing都處理好了,相當方便:

Next.js提供兩種pre-rendering的方式,一個是靜態頁面生成SSG(Static Site Generation),一個是伺服器渲染(SSR),預設為SSG,如上面建立的about頁面。
官方建議若是可以預先渲染的頁面,都採用SSG是比較好的方式,SSG的HTML是在build time建立好的,可以被CDN緩存,速度會比SSR快許多。相反的,若是頁面無法預先渲染,例如資料會頻繁更新或是會根據不同request產生不同內容,則適合用SSR。

Example:

  1. SSG: 透過外部api取得資料建立靜態頁面
使用getStaticProps透過外部api取得data傳入Article中,並渲染出畫面。
後端api回傳資料如下:
pages/article.js:
export async function getStaticProps() {
    const res = await fetch('http://localhost/redis/public/api/article')
    const data = await res.json()
    return {
        props: {
            data,
        },
    }
}
function Article({ data }) {
    return (
        <ul>
          {data.message.map((article) => (
            <li>{article.title} - {article.create_datetime}</li>
          ))}
        </ul>
    )
}
export default Article

2. SSG: 動態路由應用,建立多個靜態頁面。
後端api回傳資料:
export async function getStaticPaths() {
    const res = await fetch('http://localhost/redis/public/api/article')
    const data = await res.json()
  
    const paths = data.message.map((article) => ({
        params: { title: article.title.toString() },
    }))
  
    return { paths, fallback: false }
}
export async function getStaticProps({ params }) {
    const res = await fetch(`http://localhost/redis/public/api/article?title=${params.title}`)
    const data = await res.json()
    return { props: { data } }
}
function Article({ data }) {
    return (
        <ul>
            <li>{data.message.title} - {data.message.create_datetime}</li>
        </ul>
    )
}
export default Article
  • articles/[title].js 這種使用方式,目的為使用文章title來建立預渲染的路徑。
  • getStaticPaths: 用來生成所有需要預渲染的路徑,這邊是設定三篇文章的title。
  • getStaticProps: 根據params的文章title透過外部api取得文章資料,渲染該文章靜態頁面。
  • SSG方式需特別注意,只要DB資料有變動,例如有新增、修改文章或文章被刪除,就需要重新build code,產生新的靜態頁面。(npm run dev模式下會讓人誤以為是動態的,需特別注意)

3. SSR: 每次request頁面時,動態重新產生頁面的HTML。
export async function getServerSideProps() {
    const res = await fetch(`http://localhost/redis/public/api/article`)
    const data = await res.json()
    return { props: { data } }
}
function ArticleSSR({ data }) {
    return (
        <ul>
          {data.message.map((article) => (
            <li key={article.id}>{article.title} - {article.create_datetime}</li>
          ))}
        </ul>
    )
}
  
export default ArticleSSR
  • getServerSideProps: 每次request進來會執行這邊,取得資料後送到ArticleSSR渲染HTML。
  • 由於是每次request都會動態拿資料,因此適合變動頻繁的系統,不須重新build code。

結論:

  • Next.js框架支援SSR/SSG可以讓開發者根據情境選擇適合的用法,加上配置好的Routing,不須像React SPA轉MPA一樣要經過繁雜的設定,可說是相當的方便。
  • 關於SSR/SSG的選擇,建議除非有必要性,否則一律使用SSG速度會比較快,畢竟是預渲染好的頁面。若是使用情境會需要頻繁更動資料,無法忍受每次都要重build code的話,就選擇SSR。
  • Next.js不僅解決了SEO問題,還可以混用CSR,使用SSR/SSG,讓頁面第一次載入速度變快,小區塊UI變動則使用CSR,不必整個頁面重新生成,等於結合了各方優點,只要適當的使用,必能大大提升應用程式的使用者體驗。
即將進入廣告,捲動後可繼續閱讀
為什麼會看到廣告
avatar-img
21會員
161內容數
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Vic Lin的沙龍 的其他內容
Laravel Migrate可以用來做資料庫版本控制,對開發團隊來說,可以快速修改Schema,了解每個工程師做了什麼change,比如新增、修改哪些欄位、表格等等,是非常實用的功能。 在開始之前,須先建立好DB,並設定好.env中的DB連線config。 建立migrate指令:
假設資料情境是「每位員工可能屬於多個部門,每個部門可能包含多位員工」,這種多對多的關係。 資料情境: 程式碼: 在Model中使用belongsToMany建立多對多關係,employee_department則為中間關聯表的table name。 列出所有員工,帶上對應的部門資料: 完整程式碼:
本篇主要是要探討,with/has/whereHas/doesntHave/whereDoesntHave之間的差別,以部落格文章及留言的例子來看。 資料情境: 程式碼與結果: with是把所有文章跟留言都找出來。 has是把所有有留言的文章找出來,不包含留言。
之前在執行某些專案的時候,常看到->with()這種寫法,因此一直都很好奇到底跟->join()寫法有什麼差別,哪一種寫法效能比較好呢? 資料情境: 假設現在情境是要撈出文章跟留言,目前共有2篇文章,每篇各有4萬筆留言,也就是留言table共有8萬筆資料: 程式碼: 實驗結果: 結論:
本筆記會以簡單的例子說明,如何在Laravel中進行unit test 與 feature test。 phpunit.xml則是設定檔,可以設定哪些檔案要做測試,哪些要排除在外等等。 使用命令建立新的test case: 建立feature test: 建立unit test: 執行測試:
對於使用Laravel來講,可以直接用composer來安裝predis,可以說是相當方便: config/database.php: redis預設有16個資料庫,這邊是各個資料庫的連接設定。 要使用predis,要記得把env file中的REDIS_CLIENT改成predis。 .env:
Laravel Migrate可以用來做資料庫版本控制,對開發團隊來說,可以快速修改Schema,了解每個工程師做了什麼change,比如新增、修改哪些欄位、表格等等,是非常實用的功能。 在開始之前,須先建立好DB,並設定好.env中的DB連線config。 建立migrate指令:
假設資料情境是「每位員工可能屬於多個部門,每個部門可能包含多位員工」,這種多對多的關係。 資料情境: 程式碼: 在Model中使用belongsToMany建立多對多關係,employee_department則為中間關聯表的table name。 列出所有員工,帶上對應的部門資料: 完整程式碼:
本篇主要是要探討,with/has/whereHas/doesntHave/whereDoesntHave之間的差別,以部落格文章及留言的例子來看。 資料情境: 程式碼與結果: with是把所有文章跟留言都找出來。 has是把所有有留言的文章找出來,不包含留言。
之前在執行某些專案的時候,常看到->with()這種寫法,因此一直都很好奇到底跟->join()寫法有什麼差別,哪一種寫法效能比較好呢? 資料情境: 假設現在情境是要撈出文章跟留言,目前共有2篇文章,每篇各有4萬筆留言,也就是留言table共有8萬筆資料: 程式碼: 實驗結果: 結論:
本筆記會以簡單的例子說明,如何在Laravel中進行unit test 與 feature test。 phpunit.xml則是設定檔,可以設定哪些檔案要做測試,哪些要排除在外等等。 使用命令建立新的test case: 建立feature test: 建立unit test: 執行測試:
對於使用Laravel來講,可以直接用composer來安裝predis,可以說是相當方便: config/database.php: redis預設有16個資料庫,這邊是各個資料庫的連接設定。 要使用predis,要記得把env file中的REDIS_CLIENT改成predis。 .env:
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
上次完成到基本的CRUD及權限控制,後面花了點時間把排序、分頁、圖表總覽的部分做完,其他細節是佈署上線,一般在公司內有專屬的部門處理,僅了解一下流程。
Thumbnail
在過年期間,利用集中時間跟完Mosh Hamedani的Next.js課程,掌握了前端至後端的技術應用。本文分享了學習過程中的收穫與成果,以及對於未來應用的展望。
Thumbnail
於1935年10月30日落成為「台北鐵道工場」,二戰後更名為「臺北機廠」,曾經是臺灣鐵路車輛最具規模的維修基地。目前做為國定古蹟的鐵路相關設施,以成立「國家鐵道博物館籌備處」而保存著...
Thumbnail
活性界面製作Activa Prodations —《Next to Normal》 2023.07.30 臺中國家歌劇院 中劇院
Thumbnail
昨天到台中聽next to normal "Next to Normal" 是一部現代音樂劇作品,兼具醫學與音樂劇迷的視角,這部作品提供了一個非常深入與生動的探討,尤其是對於心理健康議題的呈現。它以劇場藝術的形式揭示了生活在現代社會中的壓力和心理健康困境。 這部音樂劇講述了一個再普通不過的中
Thumbnail
就座之後,我們翻閱菜單討論點餐內容,接著餐點陸續上桌。美麗金黃蛋酥外衣的吐司裡還夾帶著香甜花生醬,粉嫩奶油片在上頭漸漸溶化,我們快速淋上香醇的蜂蜜。菜單上說了西多士是「上帝也無法阻擋的甜點」,所以身為凡人的我們怎能忍得住呢?!
Thumbnail
[8] Hugo Gaston 法國/21歲 左手持拍,今年多在紅土上比賽,有幾項賽事是室內硬地,因此對室內硬地的適應能力不錯,尤其在前一週的巴黎大師賽表現相當優異,從資格賽開始,一路擊敗比自己排名高的對手,第三輪對上Alcaraz,第二盤從局數0比5逆轉比賽,可說是職業生涯目前為止最佳代表作...
Thumbnail
Next Gen年終賽於2017年創始,每年11月在ATP賽季結束後於義大利米蘭舉行,這項比賽有許多創新且實驗性的規則,例如:使用電子線審(鷹眼)、比賽局數減少、沒有Ad分等等。目的在於將比賽節奏加快、吸引更多年輕球迷入場觀賽,以及符合電視轉播的需求。
Thumbnail
[8] Hugo Gaston 法國 〉2000年9月26日出生/21歲 〉身高173公分/體重68公斤 〉2021出賽/9勝6負 〉排名/年初161-本周67 〉ATP冠軍/無 〉近幾年表現: ・2021 巴黎大師賽八強。 ・2021 Gstaad決賽。 ・2021 挑戰級成績32勝18負,4座亞
現在您已經安裝了 WooCommerce 的 WordPress 網站,是時候配置 WooCommerce 並開始添加一些要銷售的產品了! 配置 WooCommerce 設置 在您的 WordPress 站點中,單擊 WooCommerce 菜單選項並轉到Settings。在設置頁面中,將在不同選項
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
上次完成到基本的CRUD及權限控制,後面花了點時間把排序、分頁、圖表總覽的部分做完,其他細節是佈署上線,一般在公司內有專屬的部門處理,僅了解一下流程。
Thumbnail
在過年期間,利用集中時間跟完Mosh Hamedani的Next.js課程,掌握了前端至後端的技術應用。本文分享了學習過程中的收穫與成果,以及對於未來應用的展望。
Thumbnail
於1935年10月30日落成為「台北鐵道工場」,二戰後更名為「臺北機廠」,曾經是臺灣鐵路車輛最具規模的維修基地。目前做為國定古蹟的鐵路相關設施,以成立「國家鐵道博物館籌備處」而保存著...
Thumbnail
活性界面製作Activa Prodations —《Next to Normal》 2023.07.30 臺中國家歌劇院 中劇院
Thumbnail
昨天到台中聽next to normal "Next to Normal" 是一部現代音樂劇作品,兼具醫學與音樂劇迷的視角,這部作品提供了一個非常深入與生動的探討,尤其是對於心理健康議題的呈現。它以劇場藝術的形式揭示了生活在現代社會中的壓力和心理健康困境。 這部音樂劇講述了一個再普通不過的中
Thumbnail
就座之後,我們翻閱菜單討論點餐內容,接著餐點陸續上桌。美麗金黃蛋酥外衣的吐司裡還夾帶著香甜花生醬,粉嫩奶油片在上頭漸漸溶化,我們快速淋上香醇的蜂蜜。菜單上說了西多士是「上帝也無法阻擋的甜點」,所以身為凡人的我們怎能忍得住呢?!
Thumbnail
[8] Hugo Gaston 法國/21歲 左手持拍,今年多在紅土上比賽,有幾項賽事是室內硬地,因此對室內硬地的適應能力不錯,尤其在前一週的巴黎大師賽表現相當優異,從資格賽開始,一路擊敗比自己排名高的對手,第三輪對上Alcaraz,第二盤從局數0比5逆轉比賽,可說是職業生涯目前為止最佳代表作...
Thumbnail
Next Gen年終賽於2017年創始,每年11月在ATP賽季結束後於義大利米蘭舉行,這項比賽有許多創新且實驗性的規則,例如:使用電子線審(鷹眼)、比賽局數減少、沒有Ad分等等。目的在於將比賽節奏加快、吸引更多年輕球迷入場觀賽,以及符合電視轉播的需求。
Thumbnail
[8] Hugo Gaston 法國 〉2000年9月26日出生/21歲 〉身高173公分/體重68公斤 〉2021出賽/9勝6負 〉排名/年初161-本周67 〉ATP冠軍/無 〉近幾年表現: ・2021 巴黎大師賽八強。 ・2021 Gstaad決賽。 ・2021 挑戰級成績32勝18負,4座亞
現在您已經安裝了 WooCommerce 的 WordPress 網站,是時候配置 WooCommerce 並開始添加一些要銷售的產品了! 配置 WooCommerce 設置 在您的 WordPress 站點中,單擊 WooCommerce 菜單選項並轉到Settings。在設置頁面中,將在不同選項