最近在學習 react 的服務端渲染,於是使用 express+react 寫了乙個 demo,用於對比和客戶端渲染的差異。github 位址
先看一下效果吧:
1、訪問 伺服器端渲染 online demo
2、我們可以看到,首屏資料很快的就顯示出來了,可是頁面的進度條卻還在載入中(因為客戶端 js 很大)。
3、當進度條載入完成後,頁面才能進行互動操作(切換路由,登入等)。
4、檢視網頁源**,頁面內容都在頁面中。
效果不明顯的話,可以開啟控制台,在 network 欄 disable cache,然後重新整理。通過這次簡單的訪問,我們就能看出伺服器端渲染的 2 大特點,
首屏直出
,seo 友好
。
1、訪問 客戶端渲染 online demo
2、我們可以看到,首屏至少等待了 6 秒才渲染出來,這對於一般的使用者,是難以容忍的。
3、不過一旦渲染完成,頁面就立即可互動了(切換路由,登入等)。
4、檢視網頁源**,頁面只有乙個空 div 容器,而沒有實際內容。
通過這次訪問,我們就能看出客戶端渲染的特點,首屏載入時間長
,seo 不友好
,但可見即可操作
。
其實我們在訪問客戶端渲染的頁面時,請求到的只是乙個 html 空殼,裡面引入了乙個 js 檔案,所有的內容都是通過 js 進行插入的,類似於這樣:
正是因為頁面是由 js 渲染出來的,所以會帶來如下幾個問題:
1、頁面要等待 js 載入,並執行完成了才能展示,在這期間頁面展現的是白屏
。
2、爬蟲不能識別 js 內容,所以抓取不到任何資料,不利於 seo 優化
。
為了解決這 2 個問題,我們可以使用伺服器端渲染。
之前說道,客戶端渲染的頁面,請求到的是乙個 html 空殼,然後通過 js 去渲染頁面。那如果請求到的直接是乙個渲染好的頁面,是不是就可以解決這 2 個問題了呢?
沒錯,伺服器端渲染就是這個原理。
1、伺服器端使用 rendertostring 直接渲染出包含頁面資訊的靜態 html
。
2、客戶端根據渲染出的靜態 html 進行二次渲染
,做一些繫結事件等操作。
伺服器端沒有 dom,window 等概念,所以只能渲染出字串,不能進行事件繫結,樣式渲染等。接下來我們一起來寫乙個 react 伺服器端渲染 demo。只有第一次訪問頁面時才使用伺服器端渲染,之後會被客戶端渲染接管。
這裡使用 react-router 對前後端**進行同構。
1、客戶端
使用 react-router-dom 下的browserrouter
進行前端路由控制。
2、伺服器端
使用 react-router-dom 下的staticrouter
進行靜態路由控制,具體操作如下:
使用 staticrouter 中通過 context 可以和前端頁面通訊,傳參。在 react 中,我們常常使用 redux 來儲存資料,管理狀態。
1、客戶端
使用 redux 進行狀態管理,使用 react-redux 提供的 provider 為元件注入 store。
2、伺服器端
和客戶端一樣,但每一次接收到請求需產生乙個新的 store,避免多個使用者操作同乙個 store。
1、客戶端
使用 axios 在 componentdidmount 中請求資料。
2、伺服器端
同樣使用 axios 去請求資料,但是伺服器端不會觸發 componentdidmount 生命週期。我們可以在後端匹配到路由的時候,進行資料請求,並把資料存入 redux 中的 store,然後渲染出包含資料的 html 頁面,為了避免客戶端二次請求,伺服器端向 window 中注入 redux_store 資料,客戶端直接使用此資料作為客戶端 redux 的初始資料,以免發生資料抖動。
具體操作如下:
1、客戶端
使用 css-loader,style-loader 打包編寫好的 css **並插入到頁面中。
2、伺服器端
由於 style-loader 會插入到頁面,而伺服器端並沒有 document 等概念,所以這裡使用 isomorphic-style-loader 打包 css **。
seo 主要是針對搜尋引擎進行優化,為了提高**在搜尋引擎中的自然排名,但搜尋引擎只能爬取落地頁內容(檢視源**時能夠看到的內容),而不能爬取 js 內容,我們可以在伺服器端做優化。
外部鏈結盡可能多
多**盡量豐富
這裡借助於 react-helmet 庫,在服務期端進行 title,meta 等資訊注入。
現在,我們成功地通過伺服器端渲染解決了首次載入白屏時間
和seo 優化
。但也帶來了一些問題:
以上兩個問題歸根結底還是錢的問題。伺服器壓力大,可以通過買更多的伺服器來解決。可維護性增大,可以招募更多人來維護。但是對於小型團隊來說,增加伺服器,招募更多維護人員,都會額外增加的支出,所以在選擇伺服器端渲染時,要權衡好利弊。
如果只是想優化 seo,不妨使用預渲染來實現,推薦使用 prerender 庫來實現。
prerender 庫的原理:先請求客戶端渲染的頁面,把客戶端渲染完成之後的結果,拿給爬蟲看
,這樣爬蟲獲取到的頁面就是已經渲染好的頁面。prerender 庫在使用時會開啟乙個服務,通過傳遞 url 來解析客戶端渲染頁面,這就需要我們對伺服器端架構進行調整。
1、 nginx 判斷訪問型別通過這個 demo,讓我加深了對伺服器端的理解,如有錯誤,麻煩多多指正,謝謝大家!2.1、 使用者訪問 :直接走客戶端渲染
2.2、 爬蟲訪問 :走預渲染
如果覺得有用得話給個 ⭐ 吧。react-ssr-demo
伺服器端渲染和客戶端渲染
網際網路早期,使用者使用瀏覽器瀏覽的都是一些沒有複雜邏輯的 簡單的頁面,這些頁面都是在後端將html拼接好的然後將之返回給前端完整的html檔案,瀏覽器拿到這個html檔案之後就可以直接解析展示了,而這也就是所謂的伺服器端渲染了。而隨著前端頁面的複雜性提高,前端就不僅僅是普通的頁面展示了,而可能新增...
伺服器端渲染和客戶端渲染
不知什麼時候腦海裡突然冒出個問題,當輸入乙個 時,展現在我們眼前的資料從何而來?然後想呀想,查呀查,隨之引入了第乙個概念就是伺服器端渲染和客戶端渲染.1.什麼是伺服器端和客戶端?伺服器端 顧名思義是提供服務的,接收客戶端發出的請求,然後於response作為回應。客戶端 同理,客戶 是發請求的那一方...
React 伺服器端渲染和客戶端渲染效果對比
最近在學習 react 的服務端渲染,於是使用 express react 寫了乙個 demo,用於對比和客戶端渲染的差異。github 位址 先看一下效果吧 剛發布貌似 easy mock 官網就掛了,1 訪問 伺服器端渲染 online demo 2 我們可以看到,首屏資料很快的就顯示出來了,可...