ReactJS 與 Domcom 比較 -- domcom 好在哪裡?

來源:互聯網
上載者:User

標籤:

在John Resig設計的jQuery獨霸前端javascript多年之後,Google推出的重量級AngularJS給前端開發帶來巨大的觀念變化,給人耳目一新之感,同時也推動前端的觀念、技術和架構領域進入快速迭代,百花齊放的局面。長江後浪推前浪,AngularJS還在浪濤之巔,facebook推出的ReactJS又異軍突起,再次給前端Web應用開發的思路帶來巨大轉變,顛覆了很多剛剛成為時尚的觀念。然而ReactJS依然存在很大的問題,而Domcom做到了去繁就簡,成為一個非常簡潔優雅的架構,能極大地提高開發效率。

為什麼ReactJS能在angular之後崛起?

追尋這些演變的蹤跡,QKXue.NET總結出結論:在前端開發中javascript逐漸從幕後和龍套角色日趨吃重,最終取代html成為導演和主演,佔據了舞台的中心。jQuery,AngularJS和ReactJS既體現和推動了這一趨勢,也代表著技術發展的不同階段以及觀念的不斷流變。

為什麼ReactJS能夠從巔峰狀態的AngularJS手中搶班奪權,順利上位呢?一是因為AngularJS在技術層面還存在某些明顯的不足,體現在概念比較繁雜,學習曲線陡峭1,組合擴充能力不夠好,資料傳遞以及管理還不夠方便等等。更重要的是,AngularJS雖然引領和推動了前端的觀念演化,代表了技術發展趨勢,同時又迅速體現出滯後於觀念演化和發展趨勢的一面。AngularJS倡導單頁面應用(SPA),重視資料繫結。從進步的一面看,說明AngularJS已經開始把Web前端開發看做軟體應用開發,然而單頁面這一名詞說明它還是一種頁面化的觀念。資料繫結的思路也說明它還是把應用的主體看做是面向頁面的資料展示與互動。因此它在技術設計上依然以Html作為主導。雖然Javascript是架構的實現途徑,然而架構的整體設計意圖都是指向擴充Html的能力。

AngularJS出現之初,技術大勢和上述狀態是比較一致的。當時Web前端開發主要還是面向案頭大螢幕,基本上是以頁面為主體的網站,提供或多或少、或靜態或動態資訊服務,針對這類需求AngularJS提供了非常高端的解決方案。然而互連網迅速邁進了移動時代。新一代的web前端開發越來越象案頭系統,更加註重友好的使用者體驗,更加面向任務,而非面向資訊,因此需要更多不同的介面元素,以完成更複雜的互動。換句話說,現在web前端已經轉向為不同大小螢幕使用者設計面向Web的圖形化使用者介面(GUI),而GUI應用的中心概念是組件,不是頁面。這就決定了AngularJS(1.x)必將迎來替代者,ReactJS就是這一波浪潮中脫穎而出的明星。

React的賣點與痛點

關於React的原理與實現的文章非常多。比如2, 3, 4, 5, 6都有一些基本的介紹。關於React學習提示的文章更是遍布網路。本文對這些不作專門介紹,只談一下React的賣點與痛點。

根據我對React原理、實現的理解,對當前web前端React開發實踐的觀察,我認為React的賣點與痛點分別體現在下述方面:

賣點

更傾向Javascript
包括AngularJS在內的以前各種javascript庫都是依託於html之上的。如果說使用這些庫就象是跳芭蕾舞,那麼使用ReactJS就像是跳現代舞,整體畫風完全不一樣了,程式員更自由更有創造力了。雖然React代碼中有看起來象html的JSX代碼,實際上JSX並不是真正的html,只是一種偽裝的javascript代碼。這和jQuery,angularJS及其類似架構,emberJS(需要handleBar模板)都是完全不一樣的。
組件化編程
React是第一個以組件思維整體看待web前端開發的架構。不同於jQuery的外掛程式,也不同於Angular的指令,React的組件將資料、UI及其互動統合於一體。這種模式給了我們一種處理應用結構的新思維。
促進代碼重用
ReactJS靈活的組件組合能力大大提升了代碼重用能力。AngularJS作為一個大而全的架構,由於設計上的缺陷,重用代碼是非常不方便的。而ReactJS代碼重用的粒度和可能性都增加了。
virtual dom
由於dom的特點,virtual dom能夠在很多場合增強效能。當然這並不是絕對的。
痛點

醜陋的JSX
支援JSX的目的是為了吸引傳統的頁面設計者,照顧傳統的基於html頁面的開發習慣。然而從程式員的角度看,兩種不同風格的代碼混雜在一起是醜陋的,也是不符合純粹的程式設計語言習慣的。這是一種面對曆史傳統的被動妥協,而不是一種順應未來趨勢的主動抉擇。
不支援OOP是對更高層次代碼重用的重大阻礙
眾多著名的GUI架構都是基於OOP設計的,無一不提供一個實用的類層次體系,比如MFC,WPF,Qt,WxWidgets, Android UI,cocoa等等。 很多人在推廣ReactJS中不遺餘力地貶低OOP,拔高函數式編程。在我看來,這是對ReactJS設計缺陷的粉飾。函數式編程有其合適的應用情境,而以狀態為主的的web以及GUI絕非其所長。如果一定要將這種領域納入函數式編程風格,只能是削足適履,帶著鐐銬跳舞。因為這種思維導致的設計偏差,React不得不使用很多特殊的技巧來處理一些適合用OOP處理非常順手的情境,比如mixins(後來他們發現mixins帶來的問題後開始勸導大家不要用mixin),高階組件等等。
繁瑣的API
可能是出於設計者的編碼風格喜好,ReactJS的API顯得相當繁瑣。比較明顯的方麵包括生命週期方法的命名(componentWillMount,componentDidMount,componentWillReceiveProps,shouldComponentUpdate,componentDidUpdate
componentWillUnmount,componentDidUnmount),擷取dom節點的方法,關於refs的設計,事件方法的綁定等等。
有人可能對此不很敏感,或者認為IDE能夠解決。然而如果能夠設計更簡潔的API,少依賴於工具,總是要更好一些。在我看來,簡潔的設計才是美的設計。jQuery可以看做這方面明顯的佐證。為什麼大家喜歡使用jQuery?當然主要原因是因為jQuery解決了移植性的夢魘,提供了某些程式員歡迎的能力,但是毫無疑問其簡潔優雅的API設計也是一個賣點。反過來說,原生API不受歡迎,除了移植性問題之外,無可否認,名稱冗長難記也是一個阻礙。
更新之痛
React對組件的更新基於一種自上而下的方案。組件最初獲得初始的props和getInitialState,然而在後續調用setState時根據state的比較決定需要更新的子組件。當發現狀態沒有變化時預設是不會更新子組件的。因此,當子組件發生了沒有納入到上層組件狀態管理的改變,或者使用了可變的資料結構,都可能導致丟失本該發生的更新。彌補這種設計方案的缺陷是React倡導使用不可變資料結構、將資料全域化,集中化的原因之一。遺憾的是,我看到React的倡導者從來不提這方面的真實原因,反而文過飾非,說什麼全域資料優於局部資料,全域狀態優於局部狀態。其實,從良好的編程實踐看,狀態局部化,私人、封裝是更好的風格。否則,就無法理解為什麼各種語言要提供模組機制,要倡導少用全域變數,全域狀態,多用無副作用的函數了,也無法理解javascript漫長的解決模組化的曆程了。
React全家桶
AngularJS有概念繁雜,學習曲線陡峭之弊。ReactJS有搭配之痛。因為ReactJS設計上的不足,導致React必須使用JSX文法,盡量使用不可變資料,青睞所謂單向資料流,導致要用好ReactJS還必須搭配jsx編譯器(babel),支援flux模式的外部庫(flux/reflux/redux),有的情境還需要使用ImmutableJS,這些組合在一起被稱為React全家桶。毋容置疑,全家桶給學習使用帶來了不必要的負擔。程式員應該根據應用和領域需求來挑選搭配的庫,而不是被架構強制地選擇一組搭配的庫。
diff型virtual dom效能缺陷
目前,主流的虛擬dom方法都是類似於ReactJS的方法(比如virtual-dom這個庫)。這種方法是將產生組件內部結構代碼放置在render方法中。因此整個應用每次render都會需要重建整個應用的組件層次樹以及執行diff演算法。雖然從理論上可以從dom中刪除原來的整個dom樹,重建新的dom樹,但是這從使用者體驗和效能上都是不合適的。因此就有必要每次render時需要比較當前產生的組件層次樹和前一次緩衝的組件層次樹直接的差異,尋找最佳化的解決方案。而這種比較和替換問題的最優解演算法的時間複雜度是O(n3),當前ReactJS和類似庫的解決方案是基於某些假設做出簡化,在絕大多數情況下也能獲得非常好的效能,這就是Reac所謂的調節(Reconciliation)方案。然而,這種方案存在效能負擔:一是還是需要進行相當多的diff運算,二是可能會產生一些不必要的dom操作,三是需要較多的人工幹預,比如通過shouldComponentUpdate以及key鍵。
某個架構設計之初,總會有些局限,可能考慮了某些問題的同時忽視了另外的問題。作為架構設計者和推廣者,為了打消人們的顧慮,吸引更多使用者,擴大社區,在宣傳上對架構做出某些粉飾是可以理解的。但是,作為架構的挑選者和使用者,不應該人云亦云,而應該儘力明辨事實與廣告,分清是非;作為使用者,能做到這一點也有助於更好地使用架構,用其所長,避其所短。上述ReactJS的痛點,有的表現得是很明顯的。但是因為架構設計推廣者的一番粉飾,很多似是而非的結論竟然三人成虎,登堂入室,成為web前端開發的主流觀點。有的時候當然也會有人針對這些痛點提出某些指責和抱怨,但是卻總是面臨很多已經被宣傳所忽悠的福士的責難。這是一件很令人歎息的事情,對於這一領域的發展也形成了某些阻礙。

Domcom的解決方案

不用JSX,代碼更簡潔
在使用Javascript組件的模式下,當前的web前端已經轉入由程式員來掌控整個介面的時代。所以Domcom在API設計上徹底地傾向程式員而不是頁面設計師的習慣,目的是保證即使不用類似xml的範本語言也能寫出簡潔優雅的程式,避免混雜JSX的醜陋代碼。現有的 Domcom API完全實現了這一目標。不管是用coffee-script,或者用原生Javascript(雖然ES6會更好,即使是ES5也很可行), Domcom應用代碼的簡潔程度也勝過用JSX的ReactJS。
鼓勵函數式編程,擁抱OOP
不象React只能繼承Component類(class X extends Component,或者React.createClass({})`),也就是說所有的組件彼此之間都是平坦的,無法形成繼承層次,需要重用公用代碼需要藉助mixin或者高階組件等技巧。 Domcom自身已經提供了一組精悍的基礎類層次,使用者程式可以在此基礎上以類繼承的方式繼續擴充。比如,可以通過Tag > Button > ImageButton的方式,讓子類重用父類的代碼,勝過ReactJS使用mixin或者高階組件的權宜性方法。
簡潔的API,易學易用
Domcom在設計API時盡量簡潔,使用短名字,大多數方法和函數都只需要0-2個參數。這對學習和使用都是非常有協助的。比如Tag組件的常用方法借鑒了jQuery的API,包括prop,attr, css, show, hide, bind, unbind等。
更新方案靈活健壯,更方便擴充
Domcom中所有組件都包含標識組件有效性的資料成員,並提供了API自底向上控制組件的有效性。系統本身已經完整地實現了組件的失效管理,使用者程式不需要顯式地進行幹預。在需要更最佳化的效能時,大多數時候只需要選用更合適的響應函數即可。同時,系統也允許利用這種有效性管理機制以及提供的API開發不同的更新方案。這方面的例子可以參考NullableTagMixin。
domcom不需要全家桶
domcom在設計上盡量擁抱javascript語言的特點,不敵視javascript固有的特徵。因此,Domcom不會因為類似JSX的需求逼迫你使用babel,不會因為不可變資料的需求驅使你學習ImmutableJS,不會因為全域資料的要求而鼓動你使用flux/reflux/redux。Domcom就象jQuery一樣是一個自給自足的架構,你只要在頁面中包含domcom.js,或者用匯入domcom模組,使用dc名字空間下的API就好了。用Domcom不會因為架構的原因驅使你學習全家桶,從此你可以專註於業務需求。
更合適的虛擬dom方案,避免Diff型Virtual dom的效能缺陷
前面提到,ReactJS將組件內部結構聲明過程置於render方法之中。其實我們只要把對內部結構的聲明過程從render方法前移到建構函式中,就可以完全避免diff兩顆樹的問題。這種方案顯得更為合理自然,更加具有聲明性,還更便於管理組件的dom節點,減少dom子樹的建立/載入/卸載,實現更好的效能。
結論

綜上所述,Domcom是一款秉承React理念的web前端架構,同時又在觀念、設計和實現等方面都向前進了一步,彌補了React的缺陷。它站在巨人的肩膀上,去繁就簡,青出於藍而勝於藍,整體上是一個更好的選擇。

Talking is cheap, show me the code. 廢話少說,放碼過來。以下兩篇文章從執行個體代碼層面對兩個架構進行了一對一的比較:1. React 與 Domcom 面對面 – 評論框教程, 2. React與Domcom面對面 – 一些代碼對比。

ReactJS 與 Domcom 比較 -- domcom 好在哪裡?

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.