當前位置:
首頁 > 知識 > React 前後端同構防止重複渲染

React 前後端同構防止重複渲染

什麼叫前後端同構?

為了解決某些問題(比如SEO、提升渲染速度等)react 提供了2個方法在服務端生成一個HTML文本格式的字元串。在得到了這個HTML格式的字元串之後,通常會將其組裝成一個頁面直接返回給用戶的瀏覽器。

到這裡,服務端的活已經幹完了,然後就是瀏覽器這邊幹活。

瀏覽器拿到HTML文本後,立刻進行渲染將內容呈現給用戶。然後載入頁面所需的 .js 文件,然後執行 JavaScript腳本,然後開始初始化 react 組件…………

到這裡問題就來了。react 初始化組件後會執行組件內所有 render () 方法,然後生成虛擬DOM的樹形結構,然後在適當的時候將虛擬dom寫到瀏覽器的真實dom中。因為 react 總是根據虛擬dom來生成真實dom,所以最後會把伺服器端渲染好的HTML全部替換掉。

上面這個事情說不是問題確實也不是問題,無非就是用戶看到頁面然後「閃現」一下。說是問題還真是個問題,產品會拿著這毛病從用戶體驗的角度在各種場合和你死磕半個月。磕累了你索性把服務端渲染關了,然後運營又拿著SEO的問題準備和你開始撕逼了。

聰明如 Facebook 的工程師當然想到了這些問題,所以他們在ReactDOMServer.renderToString(element) 方法中提供了一個 checksum 機制。

關於 checksum官網 並沒有太多介紹,但是國內外的各路博客介紹了不少。我一直想找 react 開發者關於這個機制的介紹一直沒找到……。

前後端同構就是保證前端和後端的dom結構一致,不會發生重複渲染。react 使用 checksum機制進行保障。

什麼叫React首屏渲染?

簡單的說就是 react 在瀏覽器內存中第一次生成的虛擬 dom 樹。切記是虛擬 dom ,而不是瀏覽器的dom。

了解 react 的應該知道,所有 react 組件都有一個 render() 方法(如果使用function方式編寫的組件會把function里的所有代碼都塞到 render() 方法中去)。當ReactDOM.render( element, container, [callback] )方法執行時,會執行以下步驟:

所有組件的會先進行初始化(es6執行構造函數)。

所有組件的 render () 方法會被調用一次,完成這個過程後會得到一顆虛擬的 dom 樹。

react 會將虛擬dom轉換成瀏覽器dom,完成後調用組件的 componentDidMount() 方法告訴你已經裝載到瀏覽器上了。

在上面這個過程成中,步驟2完成後即為完成 react 的首屏渲染。結合 checksum 機制步驟3有可能不會執行。

當組件狀態發生變更時( setState() 生命周期函數被調用)或者 父組件渲染時(父組件的 render() 方法被調用),當前組件的 render() 方法都會被執行,都有可能會導致虛擬dom變更,但是這些變更和首屏渲染沒任何關係了。

React前後端同構首屏渲染

了解了同構和首屏渲染,就好理解如何解決首屏不重複渲染的問題了。

首先服務端渲染完之後會有一個 checksum 值寫在根元素的屬性上:

React 前後端同構防止重複渲染

這個 checksum 是根據服務端生成的HTML內容哈希計算得到的。

然後在瀏覽器載入完所有的js文件之後,開始執行前面介紹的 ReactDOM.render( element, container, [callback] ) 初始化渲染的三個步驟。當執行完第二步生成虛擬dom後,react 會根虛擬dom用相同的演算法計算一個哈希值,如果和 checksum 一致則認為伺服器已經完成渲染,不會再執行第三步。

如果 checksum 比對不一致,在 開發環境測試環境 會在瀏覽器console中輸出以下警告內容:

React 前後端同構防止重複渲染

生產環境不會輸出任何警告。

同構渲染的內容就這麼多,原理其實蠻簡單的,無非就是保證DOM一致。但是結合代碼分片、非同步載入、服務端調介面非同步組裝數據等等功能後,如何保證服務端和瀏覽器端第一次渲染的dom一致還得花不少功夫。不過原理清楚了,事情總能辦成。

具體內容可以搜索極客教程查看

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 極客教程 的精彩文章:

TAG:極客教程 |