讀書不是為了雄辯和駁斥,
也不是為了輕信和盲從,
而是為了思考和權衡。
—— 培根
複製程式碼
兩種渲染方式
為什麼會有後端渲染(伺服器渲染SSR)與前端渲染(客戶端渲染CSR)
首先理解伺服器和瀏覽器客戶端之間傳遞的是什麼: HTML、CSS、JavaScript的檔案以及資料載體json(xml)等檔案。
一開始,Web App 直接由若干 HTML、CSS、 JS 組成,每一個頁面需要特殊的邏輯,因此隨著App規模的擴大,後端網站目錄下的程式碼檔案就越來越多,而且,彼此之間是沒有同步的。比如你改了站點的佈局風格,那麼你很可能需要改動成百上千的HTML檔案,這勞動量太大了。既然如此多的HTML具有一定的邏輯聯絡,何不使用程式碼生成程式碼?於是後端模板語言誕生了,於是人們開始廣泛使用模板語言代替手寫HTML。
目前接觸到的模板語言有pug(jade)跟go template
-
pug模板示例如下:
-
go template模板示例如下:
通過後端渲染HTML,前端不需要配置路由那些步驟,只需要在需要填充內容的地方佔位即可。需要對欄位比較熟悉,還需要前後端一起聯調。
後端渲染
網際網路早期,使用者使用瀏覽器瀏覽的都是一些沒有複雜邏輯的、簡單的頁面,伺服器程式從資料庫獲取資料後,後端的程式在把HTML頁面吐給前端之前,先把HTML頁面上的特定區域、特定符號,先用資料填充,將資料載入進來生成HTML,然後通過網路傳輸到使用者的瀏覽器中解析成可見的頁面。
所謂渲染,你可以理解一種修改,渲染這詞最早來源於遊戲領域,遊戲領域又來源於現實畫畫,渲染嘛,拿著顏料往紙上塗便是。以前絕大部分伺服器都是這個模式
前端渲染
隨著前端頁面的複雜性提高,前端就不僅僅是普通的頁面展示了,而可能新增了更多功能性的元件,複雜性更大,另外,彼時ajax的興起,使得業界就開始推崇前後端分離的開發模式,即後端不提供完整的HTML頁面,而是提供一些API使得前端可以獲取到JSON資料,然後前端拿到JSON資料之後再在前端進行HTML頁面的拼接,然後展示在瀏覽器上,這就是所謂的前端渲染。
這樣前端就可以專注UI的開發,後端專注於邏輯的開發。代表是現在流行的SPA單頁面應用,例如Vue、React框架,只需要後端給我們提供介面API,前端UI、互動等全在前端進行,前後端只需要約定介面。
後端渲染和前端渲染最重要的區別在於資料填充上的區別,也就是究竟是誰來完成HTML檔案的完整拼接,如果是在後端完成的,直接填充到HTML後傳給前端,然後返回給客戶端,就是後端渲染;而如果是前端做了更多的工作完成了HTML的拼接,通過ajax或者fetch從後臺拿資料再自己填充或進行其他資料操作,則就是前端渲染
下面幾個是在網上搜到的網友對前後端渲染比較形象的比喻:
簡單來說:
後端渲染html 叫吐或者噴,機器人可以看到完整的呈現原始碼
前端模板渲染html叫填,機器人看不到完整的呈現原始碼
比如畫一張帶房子的畫:
後端渲染:後端都畫好,前端直接拿來展示給你看
前端渲染:後端把畫布,房子,房子位置等一系列資料發給前端,前端現場畫一個給你看
前端渲染和後端渲染路線
前端渲染路線
1. 請求一個HTML
2. 服務端返回一個HTML
3. 瀏覽器下載html裡面的JS/CSS檔案
4. 等待JS檔案下載完成
5. 等待JS載入並初始化完成
6. JS程式碼終於可以執行,由JS程式碼向後端請求資料(ajax/fetch)
7. 等待後端資料返回
8. 客戶端從無到完整地,把資料渲染為響應頁面
複製程式碼
後端渲染路線
1. 請求一個HTML
2. 服務端請求資料(內網請求快)
3. 伺服器初始渲染(服務端效能,較快)
4. 服務端返回已經有正確內容的HTML
5. 客戶端請求JS/CSS檔案
6. 等待JS檔案下載完成
7. 等待JS載入並初始化完成
8. 客戶端把剩下一部分渲染完成(內容小,渲染快)
複製程式碼
從後端渲染到前端渲染的變化
-
計算任務轉移
原本由伺服器執行的渲染任務轉移給了客戶端,這在大量使用者訪問的時候大大減輕後端的壓力。讓後端專注做後端應該做的事情,效能將大大提高,因為伺服器做的事情確實減小了,而現在隨著客戶端軟硬體的發展,也能處理好大多數的渲染工作了。 -
放棄前端許可權
將整個UI邏輯交給客戶端以後,一些有經驗有能力的使用者可能會劫持UI,使得他們能夠看到一些不該看到的介面。這似乎違反了安全的原則。但是“一切在前端談安全都是耍流氓”,後端不能輕信一切從前端傳來的資料,切記一定要做好過濾與驗證。只要使用SSL、遮蔽XSS、後端不出漏洞,想偽造身份劫持App還是難以做到的。
後端渲染與前端渲染的優缺點對比
後端渲染優缺點
-
優點:
- 前端耗時少,因為後端拼接完了HTML,不需要先下載一堆JS和CSS 後才能看到頁面,瀏覽器只需要直接渲染出來
- 搜尋引擎優化,因為在後端有完整的HTML頁面,所以爬蟲更容易爬取獲得資訊,更有利於SEO
- 無需佔用客戶端資源。即解析模板的工作完全交由後端來做,客戶端只要解析標準的HTML頁面即可,這樣對於客戶端的資源佔用更少,尤其是移動端,也可以更省電
- 後端生成靜態化檔案。即生成快取片段,這樣就可以減少資料庫查詢浪費的時間了,且對於資料變化不大的頁面非常高效
-
缺點:
- 不利於前後端分離,開發效率低。使用伺服器端渲染,則無法進行分工合作,則對於前端複雜度高的專案,不利於專案高效開發
- 伺服器端渲染,則前端一般就是寫一個靜態HTML檔案,然後後端再修改為模板,這樣是非常低效的,並且還常常需要前後端共同完成修改的動作
- 如果後端改了模板,前端還需要根據改動的模板再調節CSS,這樣使得前後端聯調的時間增加
- 佔用伺服器端資源,即伺服器端完成HTML模板的解析,如果請求較多,會對伺服器造成一定的訪問壓力。而如果使用前端渲染,就是把這些解析的壓力分攤了前端,而這裡確實完全交給了一個伺服器
前端渲染優缺點
-
優點:
- 前後端分離,前端專注於前端UI,後端專注於API開發,且前端有更多的選擇性,而不需要遵循後端特定的模板
- 體驗更好,比如,我們將網站做成單頁Web應用(single page web application,SPA,是載入單個HTML 頁面並在使用者與應用程式互動時動態更新該頁面的Web應用程式)或者部分內容做成SPA,這樣,尤其是移動端,可以使體驗更接近於原生APP
- 區域性重新整理,無需每次都進行完整頁面請求
- 懶載入,如在頁面初始時只載入可視區域內的資料,滾動後再載入其它資料,可以通過 react-lazyload 實現
- 富互動,使用 JS 實現各種酷炫效果
- 節約伺服器成本,省電省錢,JS 支援 CDN 部署,且部署極其簡單,只需要伺服器支援靜態檔案即可
-
缺點:
- 前端響應較慢,如果是客戶端渲染,前端還要進行拼接字串的過程,需要耗費額外的時間,不如伺服器端渲染速度快
- 不利於SEO,目前比如百度、谷歌的爬蟲對於SPA都是不認的,只是記錄了一個頁面,所以SEO很差
使用場景
不談業務場景而盲目選擇使用何種渲染方式都是耍流氓。比如企業級網站,主要功能是展示而沒有複雜的互動,並且需要良好的SEO,則這時我們就需要使用後端渲染;而類似後臺管理頁面,互動性比較強,不需要SEO的考慮,那麼就可以使用前端渲染。
另外,具體使用何種渲染方法並不是絕對的,比如現在一些網站採用了首屏後端渲染,即對於使用者最開始開啟的那個頁面採用的是後端渲染,這樣就保證了渲染速度,而其他的頁面採用前端渲染,這樣就完成了前後端分離。
- 後端渲染:相對模組化,非常適用於偏向展示性的頁面,利於SEO。而且由於是在後端就已經渲染好,所以載入體驗相對好,在網速差的時候表現明顯。
- 前端渲染:比較靈活,適用於dom操作比較頻繁或者互動比較複雜的業務場景。可以很好地維護一份model,而不用反覆請求。理論上更符合前後端分離。
為什麼前端渲染不利於SEO
如果進行了前後端分離,那麼前端就是通過JS來修改DOM使得HTML拼接完全,然後再顯示,或者是使用SPA,這樣,SEO幾乎沒有。那麼這種情況下如何做SEO優化呢?
SEO(Search Engine Optimization),中文一般譯作:搜尋引擎優化。SEO是一種通過了解搜尋引擎的運作規則(如何抓取網站頁面,如何索引以及如何根據特定的關鍵字展現搜尋結果排序等)來調整網站,以提高該網站在搜尋引擎中某些關鍵詞的搜尋結果排名
前面我們談到的SPA不利於SEO,因為就目前而言,部分搜尋引擎如Google、bing等,它們的爬蟲雖然已經支援執行JS甚至是通過AJAX獲取資料了,但是對於非同步資料的支援也還不足。
因為單頁面的情況下的頁面中的很多內容都是根據匹配到的路由動態生成並展示出來的,而且很多頁面內容是通過ajax非同步獲取的,網路抓取工具並不會等待非同步請求完成後再行抓取頁面內容,對於網路抓取工來說去準確模擬相關的行為獲取複合資料是很困難的,它們更擅長對靜態資源的抓取和分析。
vue和react實現的路由不是新的頁面,只是動態切換了頁面內容,頁面沒有過載,也就沒有網頁爬蟲爬去取資料的過程
- 後端渲染爬蟲看到的頁面長這樣:
- 前端渲染爬蟲看到的頁面長這樣:
參考資料: