最近在菲麥社羣中,有關 Redux/Vuex 是否真的須要的討論異常激烈,我認爲,在前端工程化的道路上, Redux/Vuex 很是有必要,在此前的文章中,我提到過:能夠將 Vuex 認爲是 Vue 的高級事件總線(redux 與 react 的關係類同),今天就之前後端同構爲出發點,來談談它們的高級之處html
動態網頁起初由服務器端腳本支撐,例如 Jsp、Asp 和 Php 等,也就是說,在當時,網頁都是由服務端渲染的(這裏的渲染指的是,將數據注入模板,渲染成 html,發回到瀏覽器),服務器端的 MVC 架構由此提出,模板由服務器端維護前端
得益於 Ajax 的發展,網頁開始能夠進行局部刷新,Js 經過發送 Ajax 請求拉取接口數據,再經過瀏覽器的 Dom 接口更新前端網頁。這種形式,相比於此前用戶每點擊一個按鈕、每發起一個互動皆須要經過服務器渲染,再全局刷新網頁的體驗要優異不少。既然前端有渲染的工做,那必然前端也須要模板,天然而然的衍生出前端 MV* ,基於 Angular、React 和 Vue 的各種 spa 架構,給人的感受是,你們彷佛已經暫時忘記了服務器渲染react
忘記的理由並非說 spa 已經足夠完美,spa 一樣有顯著的問題,例如,用戶必須忍受 bundle.js 下載以及隨後的前端渲染的過程當中的轉菊花過程: 編程
可是相比於先後端渲染同時存在致使的先後端須要維護兩套模板,這點小缺陷彷佛值得忍受。然而首屏直出一直以來都是 Web 應用的體驗痛點,猿類並無中止對先後端共用一套模板的探索,而且將 Js 擴展到後臺的 Node 也讓這一切成爲可能你可能知道,React 和 Vue 都有在後臺渲染相應的 renderToString 方法,和配套的實踐,先忘記這一切,假如是你來設計這一套,你會怎樣畫這個用例圖?這麼作的目的,更容易發現整個過程的難點,一塊兒來試一下 redux
圖中藍色字體中的在後端執行 jsBundle 渲染首頁 html 的步驟,是一個難點, React 和 Vue 對應的 renderToString 方法,正是爲了解決這個問題而產生後端
可是我認爲更爲關鍵的步驟在於,黃色字體中,根據後臺內置在 html 中的初始數據從新執行一次 JsBundle 渲染。這主要是因爲先後端共用了一套 Js 邏輯,因此後端執行過的渲染過程,會因爲前端 JsBundle 的執行而從新被調起,如何保證兩次的渲染結果的一致性(渲染結果一致,最好的結果是不真實反應在真實的 dom 中,不然也會致使閃爍)?前端工程化
固然,你可能會說,經過兼容性的代碼,讓前端不重複執行渲染便可,但這樣無異於不讓前端繼承後端的執行狀態,這就毫無同構可言了。因此這裏執行兩次,更爲關鍵的是,繼承後端的執行初始狀態瀏覽器
前面說了,發送到前端的 jsBundle,要要能根據服務器端內置在 html 中的初始狀態,從新渲染,而且渲染的結果要跟後端的渲染結果保持一致(最好是別在真實的反應到真實的dom 上面了),換句話說:服務器
一樣的輸入要能獲得一樣的輸出結果架構
要能高效的完成這個目標,就要求咱們摒棄面向 dom 的編程,切換到面向數據的編程中,想象一下,面向 dom 編程的時候,咱們經常須要作向某一個節點插入內容的操做,這個過程若是執行兩遍,恐怕不容易保證一致性吧。好在 React 和 Vue 都是面向數據的編程(曾經你是否是覺得它們最重要的是解決組件化而已)
獲得一樣的渲染結果,那只是完成了一個小目標,咱們的真實目的是繼承後端的初始狀態,更好的銜接後續的各類 spa 操做,那就要要求
數據源是統一的,數據狀態是能夠追溯的
Redux/Vuex 「高級」就高級在了這裏,這應該能夠回答開始關於 Redux 和 Vuex 必要性的問題了,若是還不能,那就再來理解下官方文檔的開篇所寫的動機
服務器端渲染的好處其實還遠不止此,還有 seo、靜態化等等 同構的原理歸原理,實踐歸實踐,回頭再說一說踩過的坑
想更快的瞭解,不如加微勾搭:facemagic2014