Vue 是 SPA 框架,而 Nuxt 是 Vue 生態系裏的一個能同時實現 SPA 和 SSR 的框架。SPA 的主要技術是不用重刷頁面來更新頁面內容,而是透過切換元件來達成切換頁面的效果,提升瀏覽時的流暢度,但最大缺點是不利於 SEO。
SSR 模式是較傳統的方式,在 SPA 還沒流行時主要是用 SSR,意思就是所有內容都在伺服器準備好,再把完整的 HTML 檔案傳到前端,前端只需顯示它就行了。但最大缺點是,每次跳轉頁面都要重新向伺服器發出請求,並重刷頁面,瀏覽流暢度明顯不及 SPA。但好處是有利 SEO,因為搜尋引擎能直接爬到在 HTML 上的內容。
相反,Nuxt 是一個同時能結合 SSR 和 SPA 的框架,目的是解決以上提到的 SEO 問題。在首次載入頁面時,用戶端向伺服器發出請求。伺服器會回傳兩種檔案,一是完整的 HTML 檔案,二是跑 SPA 模式時會用到的檔案。因此,在剛載入第一頁時,我們是使用 SSR 模式,即是從伺服器端把所有內容都處理好,直接把 HTML 塞回前端。之後,當用戶與網頁互動時,就會跑 SPA 模式。
以下會再詳細解說這些概念。
用 Vue 為例子,即使我們打開不同網頁,但由始至終我們仍然是在 index.html 這檔案裏。當我們切換網頁時,其實是在 index.html 此檔案裏切換不同元件。
假設我由首頁,跳到 about 頁,再跳到 products 頁。每次跳轉都不用重刷頁面,而是切換元件即可。由始至終我都是在 index.html 此檔案裏。
比起一般傳統網頁需時重新刷新和載入頁面,感覺更為順暢和快速,體驗就如使用 App 一樣順暢,也因此我們會稱為 Single Page "Application"。
SPA 依賴 AJAX 技術來實現局部更新畫面。
以最廣為人知的 Gmail 為例,打開 Gmail 看看,例如由收件匣頁面跳到草稿時,網頁 URL 尾部由 #inbox
轉至 #drafts
,跳轉時並沒有刷新頁面。如果再仔細一點看,會發現在跳轉時,只有內容會更新,最頂部的 Navbar ,以及左邊的選單都沒有太大變化。所以,其實 Gmail 主要只需信件內容,其餘部分不需要重新載入。
因此,以上面由收件匣頁面跳到草稿的情況為例,我們只需要透過 AJAX 向後端伺服器發出請求來取得資料,即是打 API 取得此 Gmail 用戶的草稿資料。在收到 response 後,把資料掉回去前端,再利用 JavaScript,只針對右邊的內容做重新渲染,把從 response 抓回來的資料渲染上去。
SPA 另一個特點是在客戶端讀取 JavaScript 來渲染畫面內容,而非等後端把整個網頁內容都渲染好並掉回前端。
當用戶載入網頁時,這時候不用等後端把整個網頁內容回傳並顯示,瀏覽器只需等待伺服器回傳 HTML、CSS 和 JavaScript 這三種檔案。接著瀏覽器會把打包在 JavaScript 裏的資料內容渲染成畫面。
以 Vue CLI 所開發的網站為例,使用 npm run build
來產生 dist 資料夾打包檔案,再用 live server 插件來預覽 dist 裏的 index.html。當你用 page source 來看網頁的原始碼時,會發現此頁面並沒有資料內容,除了只有基本的 HTML,就只有一堆 CSS 和 JavaScript 檔案:
但如果是用檢查元素的方式去看,就會發現內容,例如是 nav
的內容:
以上差別明顯可見,網頁的內容都是由瀏覽器透過讀取 JavaScript 來渲染。
補充一點,Vue、React、Angular 三大前端框架都是 SPA 框架(Single Page Application)。SPA 是一個開發模式,正如常見後端會採用 MVC 模式一樣,所以即使不使用 Vue、React 這些框架,用原生 JavaScript 或 jQuery 等都可以完成一個 SPA 的網頁。
SSR(server side render)就是 SPA 還沒出現時所採用的傳統做法。重點如下:
常見做法透過 MVC(Model、View、Controller)的架構,在後端完成:
前端的職責相對少,只需直接把收到的 HTML 檔案顯示出來就完成。
每當用戶訪問一個網頁,後端就要回傳一次新的 HTML 檔案給前端。因此每次跳轉網頁時都會重新刷新頁面,導致使用流暢度明顯比 SPA 差。
雖然聽來 SPA 比較優勝,但是兩者都有限制。
SPA 優點:
SPA 限制:
SSR 優點:
SSR 限制:
為了解決 SPA 的 SEO 問題,最常見方法之一是使用前端的 SSR 框架。在 Vue 的生態圈就是使用 Nuxt.js 框架。核心概念就是在首次載入畫面時用 SSR 模式,跑完一次 SSR 後,往後所有請求都是 SPA 進行,運作流程如下:
這二合一的解決方法就能同時兼顧 SEO 和使用者體驗。較明顯的代價是:
雖說 Nuxt 是 SPA + SSR 框架,但在 Nuxt 裏,只不過它預設是 SPA + SSR 模式,如果你只想要 SPA,也可以在 Nuxt 的 nuxt.config.js
檔案裏做設定。
預設模式是 universal,即是 SSR 加 SPA。以下示範用 Nuxt 建立一個專案,並在 Nuxt 載入第一頁面時檢查原始碼,會發現有網頁內容。有找到在網頁中 Welcome to your Nuxt Application 這一句:
把設定轉為 SPA 模式,就沒有網頁內容,只是載入 JavaScript 檔案。沒找到在網頁中 Welcome to your Nuxt Application 這一句:
原因就如以上提過,因為 SPA 是以讀取 JS 檔案來渲染內容,並不像 SSR ,直接在 HTML 裏就找到內容。
總結一下重點:
Server-side rendering with Vue and Nuxt.js
Server side render (SSR) 是什麼嗎? 為何要用 SSR ? 跟 SPA 和 SEO 又有什麼關聯?
前後端分離與 SPA
Vue 服务端渲染原理及入门