摘要:從angular的誕生獨步天下,到現在三大框架平分天下,基本形勢已經趨于穩定。每一個框架從誕生到受歡迎,都有其特定的原因和背景。不同的開發者選擇時,也是依據于其特定情景下的原因和背景。
??不知道大家有沒有發現,這三個框架除了都是前端框架之外,還大有搞基的成分存在。注意他們三個的名字,分別以v,a,r 開頭,我這么一說,你是不是忽然間就想到了什么。哈哈,正是如此,將他們組合起來不就是java中無處不在的鬼東西么?var (當然純屬于開玩笑的)??var關鍵字,是js的變量聲明關鍵字,可以說,它是js得以運行的核心關鍵字,因為要想一段代碼運行,首先得有各種變量和邏輯判斷做支撐,而在es6之前,js能聲明變量的,就它一個。這似乎也是暗示了vue,angularjs,react這三個框架的不可替代性啊,也不知道當時這三個框架的作者起名時的想表達的特殊含義是什么,但偏偏就剛好對上了。當然,反過來說,也有可能是起var關鍵字的這個人,當時考慮得面面俱到。雖然看上去是巧合,但我總感覺這之中總有一種道不明的關系。雖然vue是后起之秀,但就目前的受歡迎程度來說,好像就是這個順序,至少國內現在肯定是這樣的。??有了這三個框架之后,我們告別了以前jquery面條式的代碼,也擺脫了到處操作dom元素帶來的繁瑣,模塊業務劃分更清晰。這三個框架的出現,不僅讓前端的工作得以高效,也讓后端省了不少事,比如,路由控制。在以前,干后端是對決要比前端高一個檔次的,但現在,完全不一樣了。如果有一個牛逼的前端,后端差不多只需要會增刪改查的基本業務就能完全搞定一個web應用。當然,這里只是針對代碼部分,搭建服務器之類的另當別論。
??我們主要從數據流、視圖渲染、性能與優化、模塊化組件化等四個方面來作比較 1、數據流
??Angular 使用雙向綁定即:界面的操作能實時反映到數據,數據的變更能實時展現到界面。
1.1、它的實現原理:
??scope.scope.scope.scope.scope.$watch時只為它傳遞了一個參數,無論作用域中的什么東西發生了變化,這個函數都會被調用。在ng-model中,這個函數被用來檢查模型和視圖有沒有同步,如果沒有同步,它將會使用新值來更新模型數據。
1.2、雙向綁定的三個重要方法:
apply()digest()watch()??在angularjs雙向綁定中,有2個很重要的概念叫做dirty check,digest loop,dirty check(臟檢測)是用來檢查綁定的scope中的對象的狀態的,例如,在js里創建了一個對象,并且把這個對象綁定在scope下,這樣這個對象就處于digest loop中,loop通過遍歷這些對象來發現他們是否改變,如果改變就會調用相應的處理方法來實現雙向綁定??Vue 也支持雙向綁定,默認為單向綁定,數據從父組件單向傳給子組件。在大型應用中使用單向綁定讓數據流易于理解。
1.3、臟檢測的利弊
??和ember.js等技術的getter/setter觀測機制相比(優):??getter/setter當每次對DOM產生變更,它都要修改DOM樹的結構,性能影響大,Angular會把批量操作延時到一次更新,性能相對較好。??和Vue相比(劣):??Vue.js 有更好的性能,并且非常非常容易優化,因為它不使用臟檢查。Angular,當 watcher 越來越多時會變得越來越慢,因為作用域內的每一次變化,所有 watcher 都要重新計算。并且,如果一些 watcher 觸發另一個更新,臟檢查循環(digest cycle)可能要運行多次。 Angular 用戶常常要使用深奧的技術,以解決臟檢查循環的問題。有時沒有簡單的辦法來優化有大量 watcher 的作用域。Vue.js 則根本沒有這個問題,因為它使用基于依賴追蹤的觀察系統并且異步列隊更新,所有的數據變化都是獨立地觸發,除非它們之間有明確的依賴關系。唯一需要做的優化是在 v-for 上使用 track-by。??React-單向數據流??MVVM流的Angular和Vue,都是通過類似模板的語法,描述界面狀態與數據的綁定關系,然后通過內部轉換,把這個結構建立起來,當界面發生變化的時候,按照配置規則去更新相應的數據,然后,再根據配置好的規則去,從數據更新界面狀態。??React推崇的是函數式編程和單向數據流:給定原始界面(或數據),施加一個變化,就能推導出另外一個狀態(界面或者數據的更新)。??React和Vue都可以配合Redux來管理狀態數據。
2、視圖渲染 Angular1
??AngularJS的工作原理是:HTML模板將會被瀏覽器解析到DOM中, DOM結構成為AngularJS編譯器的輸入。AngularJS將會遍歷DOM模板, 來生成相應的NG指令,所有的指令都負責針對view(即HTML中的ng-model)來設置數據綁定。因此, NG框架是在DOM加載完成之后, 才開始起作用的。
React
??React 的渲染建立在 Virtual DOM 上——一種在內存中描述 DOM 樹狀態的數據結構。當狀態發生變化時,React 重新渲染 Virtual DOM,比較計算之后給真實 DOM 打補丁。Virtual DOM:??提供了函數式的方法描述視圖,它不使用數據觀察機制,每次更新都會重新渲染整個應用,因此從定義上保證了視圖與數據的同步。它也開辟了 Java 同構應用的可能性。??在超大量數據的首屏渲染速度上,React 有一定優勢,因為Vue 的渲染機制啟動時候要做的工作比較多,而且React 支持服務端渲染。React 的Virtual DOM 也需要優化。復雜的應用里可以選擇 1. 手動添加shouldComponentUpdate 來避免不需要的 vdom re-render;2. Components 盡可能都用 pureRenderMixin,然后采用 Flux 結構 + Immutable.js。其實也不是那么簡單的。相比之下,Vue由于采用依賴追蹤,默認就是優化狀態:動了多少數據,就觸發多少更新,不多也不少。React 和 Angular 2 都有服務端渲染和原生渲染的功能。Vue.js不使用 Virtual DOM 而是使用真實 DOM 作為模板,數據綁定到真實節點。Vue.js 的應用環境必須提供 DOM。Vue.js 有時性能會比 React 好,而且幾乎不用手工優化。
3、性能與優化
??性能方面,這幾個主流框架都應該可以輕松應付大部分常見場景的性能需求,區別在于可優化性和優化對于開發體驗的影響。Vue 的話需要加好 track-by 。React 需要 shouldComponentUpdate 或者全面 Immutable,Angular 2 需要手動指定 change detection strategy。從整體趨勢上來說,瀏覽器和手機還會越變越快,框架本身的渲染性能在整個前端性能優化體系中,會漸漸淡化,更多的優化點還是在構建方式、緩存、圖片加載、網絡鏈路、HTTP/2 等方面
4、模塊化與組件 Angular1 -> Angular2
??Angular1使用依賴注入來解決模塊之間的依賴問題,模塊幾乎都依賴于注入容器以及其他相關功能。不是異步加載的,根據依賴列出第一次加載所需的所有依賴。??可以配合類似于Require.js來實現異步加載,懶加載(按需加載)則是借助于 ocLazyLoad 方式的解決方案,但是理想情況下應該是本地框架會更易懂。??Angular2使用ES6的module來定義模塊,也考慮了動態加載的需求。
Vue
??Vue中指令和組件分得更清晰。指令只封裝 DOM 操作,而組件代表一個自給自足的獨立單元 —— 有自己的視圖和數據邏輯。在 Angular1 中兩者有不少相混的地方
React
一個 React 應用就是構建在 React 組件之上的。??組件有兩個核心概念:props,state。 一個組件就是通過這兩個屬性的值在 render 方法里面生成這個組件對應的 HTML 結構。??傳統的 MVC 是將模板放在其他地方,比如 標簽或者模板文件,再在 JS 中通過某種手段引用模板。按這種思路,想想多少次我們面對四處分散的模板片段不知所措?糾結模板引擎,糾結模板存放位置,糾結如何引用模板。??React 認為組件才是王道,而組件是和模板緊密關聯的,組件模板和組件邏輯分離讓問題復雜化了。所以就有了 JSX 這種語法,就是為了把 HTML 模板直接嵌入到 JS 代碼里面,這樣就做到了模板和組件關聯,但是 JS 不支持這種包含 HTML 的語法,所以需要通過工具將 JSX 編譯輸出成 JS 代碼才能使用(可以進行跨平臺開發的依據,通過不同的解釋器解釋成不同平臺上運行的代碼,由此可以有RN和React開發桌面客戶端)。
??年輕的程序員都是好奇的貓,玩過一個又一個的前端框架。從毛球上弄出一條條的線,玩啊玩,最后這一個個的框架在腦子里攪漿糊。有太多的選擇,就是一件麻煩的事;沒有選擇時,就是一件更麻煩的事;有唯一的選擇時,事情就會變得超級簡單。??當一個程序員學了某個最新的框架之后,通常來說這個框架有著更多的優點,這個時候最容易出現的想法就是替換現有的框架,科室現有的框架并沒有什么大的問題,并且評估不充分的時候,新的框架則會有更多的風險。??所以最后總結一下:技術選型沒有銀彈,沒有一個框架能夠解決所有的問題。這時,為了更好的考量不同的因素,你需要列出重要的象限,如開發效率,團隊喜好,開發周期等時機情況選擇哪個框架最合適你當前的團隊和項目。