進度條

前後端分離要用 SSR? Server side render (SSR)是什麼嗎?跟 SPA 和 SEO 又有什麼關聯?

SPA 對 SEO 不好?為了 SEO 所以要捨棄 CSR ? 多了解一點原理答案就自然浮現了!

作者: 進度條編輯群 更新日期:

在你學玩基礎的 JavaScript 以後,可能開始嘗試玩 React 或是 Vue 等比較酷炫的前端,做出了所謂的單頁面應用程式 - Single Page Application (SPA),讓網頁動作的萬分順暢,就像是桌面應用程式一般,都不需要跳頁,

 

突然間你可能查到了某個關鍵字。

 

SPA 對 SEO 不好,要用 SSR 才能解決問題!

 

「 SSR 」?
 

是要抽卡的意思嗎? 十連抽我在行的!畢竟升到課長這個職位也滿久了。

但是怎麼在 React 網站上找都找不到入金的方案

(Vue 倒是有成為贊助的按鈕,不過不是當然不是指這個)。

 

上面雖然只是一個簡單的冷笑話,不過這也反映出來習慣使用英文縮寫的問題,即使在同一個產業下,也常常會發生誤會。總之接下來我們就開始解釋這些名詞所代表的意義,以及在程式邏輯上面會擁有怎樣的優缺點。

 

以下為了方便,所以我們分段來講。

 

網站基本原理複習

首先先快速的複習一下網站的原理,網站基本上就是文字,以特殊的格式寫成,也就是 HTML。網站的最初目的就是顯示畫面與內容,只要善用 HTML / CSS 即可完成美觀的畫面。

 

 

要轉變 HTML CSS 語法則需要使用瀏覽器 (Browser),也就是我們常見的 Chrome / Safari 等。瀏覽器除了轉換程式碼顯示畫面外,還有很多功能,這些功能都有跟 JavaScript 做連接。所以我們可以用 JavaScript 去控制這些功能。最常提到的就是 BOM (Browser Object Model - 瀏覽器物件模型) 與 DOM (Document Object Model - 文件物件模型)。

 

DOM 就是顯示文章,可以想成 HTML / CSS  程式本身,操作他們就可以改變畫面。

 

BOM 就是其他的功能,例如網路連線, Local Storage...等,基本上所有瀏覽器提供給 JavaScript 控制的功能都在 BOM 底下。

 

如果了解 JavaScript 的話,就會知道有 window 物件,一般來說 BOM 所指的那個 Object,DOM 所指的的話就是 document 這個物件。在一般瀏覽器下,所有的 Object 如果沒特別指名就宣告的話,其實就是掛在 window 底下。如果今天有任何物件的使用方式是 window.物件 。那 window 就可以省略不寫。

 

所以我們操作 document 的時候例如:document.getElementById 完整的寫會是 window.document.getElementById 。因此很容易就可以發現 DOM 是掛在 BOM 底下。

 

一般網站為了每個頁面產生不同的內容,所以會將資料儲存在資料庫裡面,再經由應用程式做處理,最後產生出 HTML 內容。所以這種情況下前端瀏覽器裡面也不會需要做什麼除了動畫以外的 DOM 操作。

 

也就是說前端的電腦沒有特別的事情,也不會有特別的消耗,後端的 Server 伺服器倒是滿忙的,每個訪問都有一堆事情要做判斷來決定畫面如何產生。

 

book-computer-design-development-326424.jpg

 

AJAX 、SPA 與 CSR

AJAX (Asynchronous JavaScript and XML) 發明了以後,前端花樣就變得很多,最後的完成結果就是 SPA - Single Page Application 單頁面應用程式

首先「單頁面應用程式」 並不需要 React 或是 Vue 即可完成。用一般的純 JavaScript 或是 jQuery 也可以實現。只是在資料與畫面同步上面,只要「單頁面應用程式」 複雜,就很難維護。所以其實這些進階前端解決的問題是資料與畫面管理問題,而非專門用來製作「單頁面應用程式」。

 

接著我們來講 CSR,Client Side Rendering 客戶端繪製 ,也就是在客戶端用資料繪製出 HTML / CSS 等內容再塞進 DOM 裡面呈現畫面。

 

主要的實作方式會分兩個階段,第一階段是在先跟 Server 取得小量的 HTML,之後瀏覽器顯現後再利用 AJAX 發出第二次請求(Request), 通常是利用 BOM 所提供的xmlhttprequest 或是 fetch。之後才會取得更多的資料,並透過 JavaScript 把資料轉換成 HTML,塞進 DOM 把頁面完整的描繪出來。

 

 

 

這個的好處有幾點,但是必須要對 Server 動作有些概念才會了解。

 

首先一個 request 對於 Server 來說多半是一個 process 程序。單一程序,尤其是網站,通常是逐步執行的。所以假設有一個頁面,其實是由 3 個功能組成的。這時候如果有一個功能特別的耗時,比方說要花 60 秒,其他的功能都幾乎不消耗時間。這時候這個頁面就會需要 60 秒才會回應,使用者早就等得不耐煩了。

 

如果這時候改成用 CSR 的話,是情況而定,但基本上繪製一個頁面會是由一個 原本的 request + 2 ~ 3 個 AJAX request 組成。這時候如果把花時間的功能放在 AJAX 去驅動的話。就可以秒回只少擁有其他兩個功能的頁面,另外一個就讓他先轉圈圈就好。這樣使用者也比較不會不耐煩,在使用者體驗上面也比較好。

 

 

有一些功能其實也不需要一開始就繪製,比方說購物車的 mini cart 功能,每次訪客點擊再即時利用 AJAX 抓取最新的同步資料是比較好的做法,畢竟現在很多人都同時開 APP 和 網頁再下單。這樣才不會需要顧客手動更新頁面。

 

但是這乍聽起來似乎合理,不過以首頁為例,因為由於繪製頁面的步驟需要多次 request 請求,所以一開始使用者會看到一個不完整的頁面,只要請求尚未完成,那該區塊就會顯示灰白色,並且無法使用。雖然我們可以使用一個 Loading 的轉圈圈蓋在上面,讓使用者避免看到讀取不完全的首頁資訊,但這樣也意味著,要完整描繪出首頁內容,需要花上較多的時間。尤其是如果上面範例說的 60 秒的功能是這個頁面的主要功能,那其他內容先出來也不會比較理想多少。

 

其次,一個 Request 對 server 代表一個 process,每個 process 的產生對於系統都會有額外的資源分配問題。像是 Apache / httpd 預設可能同時只有 10個 process可以運行。厚重的 process 固然佔用效能時間比較多,但是輕量的 process 可能同時佔據比較多的數量。這中間的平衡就也是一個系統調整上的施力點,都要視專案來做客製化調整比較好。

 

所以 CSR 就像在超市買菜回家慢慢煮一樣,一次只能上一道菜,這樣等菜都做完才開動,你可能已經飢腸轆轆。但 CSR 的好處是已經描繪完成的部分,功能完整,所以你可以先行使用那些功能。就像飯還沒煮好沒關係,不如先吃點菜止飢。

 

 

SEO - Search Engine Optimization 搜尋引擎優化

 

接著來講 CSR 最大的缺點,其實也就是上面所說的問題,「頁面不完整」所帶來最棘手的問題。

 

 

 

SEO 從名稱上來講就跟「搜尋引擎」有關,最有名、最重要的當然就是 Google。Googel 在有人使用關鍵字搜尋的時候,會由自身的資料庫拉出最適合的幾個結果,每頁預設就是 10 個上下。這個搜尋結果對於商店異常的重要,搜尋量高的關鍵字首頁的前三位置,就跟商業區的一樓黃金店面一樣值錢。特別值錢的關鍵字如果買廣告的話可能一個點擊就要 2 ~ 10 塊美金(動態競標價格),所以老闆絕對非常重視這塊。

 

Google 除了你自己給的資料外 (Sitemap),還會利用外部連結,之類的方式去搜集相關資料。其中還有頁面標題、敘述等。整個 SEO 評分是隨時在調整的,當然 Google 也有說一些標準,照著做即可。不過其實 Google 對你的網站「內容」也是會搜集的。因此如果他進去搜集資料的時候你的 AJAX 沒有發動的話,那他不就覺得你的頁面「沒有內容」?因此至少你該頁的 SEO 分數就會非常的低。自然搜尋的流量就不會進來。

 

當然,有人說搜集資料的爬蟲可能不會執行 JavaScript 語法,所以爬蟲看到的都會是空的。這個說法算是半對多一點。首先如果你自己使用 Curl 或是 Postman 等程式發動 http request,就會發現這是事實。但是 Google 有講說他們的爬蟲是會執行 JavaScript 的,不用擔心。

 

不過之所以說這是半對「多一點」的原因是因為,Google 並沒有說他會在該頁面待多久。所以如果你的 AJAX 有可能發生太久的情況,或是平常很快,但人多的時候 Server 塞車就很慢。或是 AJAX 有串連(就是一個完成後才做另外一個),那就很可能會讓 Google 的爬蟲抓不到內容。

 

通常爬蟲對於第一個 request 會比較通融一些,雖然花的時間太久他一樣會降低 SEO 分數,不過至少他會等的比較久,而 AJAX 的發動很多都是無意義的小功能,所以他其實很難確定哪個 AJAX 是需要等的。在這種情況下,如果是你來設計,大概也不太會等吧?

 

 

macbook-laptop-smartphone-apple-7358.jpg

 

SSR - Server Side Rendering 伺服器宣染

所以在單頁面應用程式的前提下,SSR - Server Side Rendering 伺服器宣染的名詞就被提出了。Server Side,顧名思義就是從伺服器(Server)端,取得資料以後,繪製出完整的 HTML 頁面。

 

 

這時你就會發現...這不就是傳統的方式嗎?

所有的後端框架都可以實作 SSR ,而且這就是他們的主要功能。

 

 

不過如果要嚴格定義現在說的 SSR,比較接近「如果在使用 React / Vue 的情況下」如何把 SPA 應用程式改成 SSR。也就是 React 和 Vue 能不能在 Server 執行?因為 React 和 Vue 都是 JavaScript 製作的,所以搭配 Node.js 確實可以解決。

 

以 React 來說,目前最熱門的解決方案就是 Next.js 和 Gatsby,以 Vue 來說的話就是 Nuxt.js 。他們兩個都是要安裝在伺服器上,可以直接使用 SPA 的程式再去部分改編變成 Server Side 的程式。因為小編玩過的只有 React + Next.js,所以用 Next.js 大概解釋一下他的"行為"。

 

基本上就是 React 原本 CSR 在會在 HTML Load 完成之後執行一次 AJAX,之後再利用資料繪製畫面,而這個第一次改成在 Server 上執行,所以之後的動作都還是在 Client Side 執行。這樣主要的商業邏輯程式碼就不太需要改變,原本 Client side 的程式碼還是會送出到 Browser 裡面去。

(但是 SPA 改成 SSR 當然還是有滿多需要修改的地方,代價視你的專案複雜度而定)

 

 

 

 

但用這種 SSR 方式就是唯一解嗎?沒有其他的代價嗎?SPA 完全不該用嗎?

 

其實是有的。

 

首先,SEO 的問題其實可以使用一般的框架搭配適度的 SPA 程式去解決,像 Next.js 之類的 SSR 本質上有幾個麻煩點。

 

第一個麻煩點是,SSR 寫起來比較像 SPA 寫完後再加程式碼,然後還有相容性問題,畢竟可能不是同一個作者寫的,這樣在維護開發上面會變重。

 

第二個麻煩點是,即使是 Server Side 在執行 ,但是多半沒有常用來做 API Server 的 Laravel, Ruby on rails 之類的對資料庫與其他服務來的在行。畢竟 SSR 主打還是輕量與 Server Side 去執行對應的 React 或是 Vue, 有種專用程式的感覺。在取得資料上面多半也是在透過 API 去取得,因此實務上你會有兩套「後端」程式。一個是「前台」的後端程式,另外一個是 API Server。

 

 

第三個點是,有很多情況 SEO 其實不重要,例如需要登入後才能執行的頁面。比方說 Saas 服務的 Dashboard 這種,通常這種頁面才是真的複雜的頁面,因為會有很多商業邏輯,而且這種頁面每一個使用者都要登入後才能看到,也會因為購買的權限不同之類的而看到的內容會不一樣。Goolge 等爬蟲也不會有登入的可能性。所以直接使用 SPA 即可,寫起來也方便很多。

 

第四個點是也是 SEO 關聯的點。一般來說一個頁面其實有很多對爬蟲不重要的內容,比方說廣告,引人注目的動畫等。所以常見另外一種做法就是用一般的 backend framework 例如 Larevel / Ruby on rails 等,render 的時候一起把 meta 和重要文字內容先一起輸出,剩下其他的功能用 AJAX 或是 SPA 補齊。也可以先把 Data 用 json 文字的方式存在頁面之中並且在畫面上隱藏起來。單純要解決 SEO 方法很多種,也都有適合與不適合的情況,總之不是只有 SSR 單一解決方案而已,也不見得對你來說它是最好的解決方案。

 

而且 SSR 如果用在流量過高的服務,也會像傳統網站一樣造成Server端的效能吃重,可能會造成反效果。所以有些頁面像是留言板,或是分類檢索,查詢等有著單一使用目的的頁面,其實使用 CSR 也會有好處的,因為主要功能可以先部分讀取完成,儘管其他畫面還在 Loading 造成灰白色無法使用,但因為主要功能已經可以使用了,所以這部分使用者可能也不會備感困擾。

 

因此有時候事情不需要想說只有一就沒有二,混合式使用(Hybird)而這樣也可以成功減輕Server的負擔呢!

 

 

最後來個結論,到底是 SSR 好還是 CSR 好?

 

其實就會是目的取向,你會希望使用者快速一次看到所有的資訊,還是其實部分功能可以使用,就會成為一種取捨,最重要的,每一種方法都各有優缺,效益面上的決定,才會是最重要的考量。

 


最後,如果你喜歡我們的文章,別忘了到我們的FB粉絲團按讚喔!!

Small logo

進度條編輯群

進度條編輯團隊