本文發表於個人GitHub轉載請註明出處
什麼是同構:
- 客戶端渲染:頁面在 JavaScript,CSS 等資原始檔載入完畢後開始渲染,路由為客戶端路由,也就是我們經常談到的 SPA(Single Page Application)。
- 服務端渲染:頁面由服務端直接返回給瀏覽器,路由為服務端路由,URL 的變更會重新整理頁面,原理與 ASP,PHP 等傳統後端框架類似。
- 同構:英文表述為 Isomorphic 或 Universal,即編寫的 JavaScript 程式碼可同時執行於瀏覽器及 Node.js 兩套環境中,用服務端渲染來提升首屏的載入速度,首屏之後的路由由客戶端控制,即在使用者到達首屏後,整個應用仍是一個 SPA。
簡而言之,同構是服務端直出和客戶端渲染的結合
同構的優點:
- SEO更友好。
- 整個頁面級別的應用會使得瀏覽器在解析dom完成之後馬上有東西可以渲染,減少渲染時間(首屏優化)。
- 服務端和客戶端維護一份程式碼就行了。
- 開源福利:React16的釋出通過重寫了用於服務端渲染的renderToString函式,將渲染速度提升至v15的3倍。
- 等等
當然,同構也沒有這麼好,具體的的選擇還是看業務的,權衡開發(遷移)成本,效能影響等等諸多因素。
那麼問題來了:)
如果,我嘗試下 React服務端渲染,但又不想自己一開始就糾結於較繁瑣的配置呢?
很多人的開發都會選用一個現有的腳手架開始,那麼如何選用一個腳手架呢?
關於一個框架的腳手架,在網上經常看到開發者這樣說:
I'm looking for a very simple starter pack... I don't need all the hoopla.
的確,對一個腳手架專案而言,它需要有所有你想要的,不需要有你不想要的。
react官方的腳手架create-react-app的README中提到 現階段不支援直接提供服務端渲染。
那麼有哪些支援同構渲染的腳手架呢?
比如這些:
這些腳手架各有各的特點,有的依賴多,有的依賴少,有的效能好,有的針對某一個痛點解決...
下面隆重介紹今天的主角 ———— razzle:
razzle 是一個把所有於服務端渲染相關的繁瑣配置抽象成了單獨的一個依賴,
給你類似於create-react-app的開發體驗,
但是把剩下的架構決策權,比如 框架選用,路由系統的選擇、資料獲取方式全都交給了開發者自己,充分符合上面說的:
have everything you need and nothing you don't.
razzle 和上述提到的其他支援同構渲染的框架的 最大不同 在於他能過抽象依賴,能夠提供類似create-react-app
的開發體驗,這就意味了給了開發者很大的自由度去選擇自己順手的,自己看得上眼的react生態裡的庫,razzle提供豐富的examples,幫助開發者能夠快速的結合一些流行的成熟的庫,比如用typescript進行開發,通過結合react-redux做狀態管理,比如通過結合react-router做路由系統,通過結合react-loadable做到元件級別的程式碼分割和懶載入等等很多。
razzle 的理念決定了它不只支援React,
還支援Reason,Elm,Vue,Angular,和未來的新框架:)
專案的主要的優點有:
- 開發環境模組熱替換,無需重啟就可以看到效果
- 你最喜歡的ES6 支援
- 與create-react-app 相同的 css 設定
- 很多框架的支援
- 預設Jest
- 零配置服務端渲染
關於同構有一些誤區,列幾個熟悉的:
- 同構效能沒有客戶端渲染好?網路流量高峰的時候,轉到客戶端渲染並不會起很大作用。ssr在服務端的渲染其實是非常快的,儘管這裡提供不了精確的資料支援,但是看了很多部落格上都提到過這種觀點。
- 同構容易引起記憶體洩漏?其實並不是,只要注意不要盲目的在定時的函式體中向全域性的陣列push東西等等,注意組建生命週期componentDidMount中放置服務端執行不了的程式碼,並且注意在用一些如window變數前先進行判斷就好,並不是很容易導致記憶體洩漏。
理解還不是很成熟,希望能與大家交流討論。
筆者是razzle的專案使用者,受益者,希望能讓更多的人看到這個專案,未來一起讓他更好。
關於同構的一些其他文章,也是本文的很多參考:
- What is an isomorphic application?
- D2 - 打造高可靠與高效能的React同構解決方案
- Here’s Why Client-side Rendering Won
- 服務端渲染與 Universal React App