文章翻譯:康楊
發(fā)表時(shí)間:2015 年 7 月 29 日
原文作者:Amit Kaufman
文章分類:Web 開發(fā)
在如今 Web 開發(fā)的過程中,我們到需要使用 JavaScript 語言。不同的 JS 語言存在著不同的優(yōu)劣性,優(yōu)秀的 JS 語言會(huì)降低我們開發(fā)時(shí)的難度和增加我們產(chǎn)品的質(zhì)量。Angular 與 React 作為兩種常用 JS 語言,存在著各自的優(yōu)缺點(diǎn)。
不久前,我們的團(tuán)隊(duì)必須為 Wix 的旗艦產(chǎn)品選擇一種隨處可見的網(wǎng)絡(luò)編輯技術(shù)。這是一個(gè)極其龐大的單頁申請(qǐng),包含復(fù)雜的資金流動(dòng),其它內(nèi)部框架和服務(wù)器之間的信息交換,以及許多用戶體驗(yàn)。這款產(chǎn)品由 40 多個(gè)開發(fā)者共同開發(fā)。關(guān)于技術(shù)的選擇是使用 ReactJS 或者 AngularJS 。這兩者我們都曾使用過,并且糾結(jié)于 Angular 便于操作的編譯說明以及 React 的簡(jiǎn)單。我們展開了一場(chǎng)概念上的證明,最終導(dǎo)致我們得出了一個(gè)平分秋色的結(jié)果。這篇文章就是關(guān)于兩者之間的比較以及他們不分上下的結(jié)果。
包裝是按照你的想法運(yùn)行和展開你自己代碼的能力。為了達(dá)到最快的加載時(shí)間,我們想要在最開始加載最小的量并且維持需求。這也讓我們能夠繼續(xù)發(fā)展新的特性而不緩慢降低加載時(shí)間。
Angular 這樣做的能力非常有限(主要在 HTML 模板),當(dāng)我們按照意愿去調(diào)整它時(shí),它看上去像代碼的堆砌。
簡(jiǎn)單來說,我們發(fā)現(xiàn) Angular 太僵硬死板。然而 React 并不這樣,它是簡(jiǎn)單的 JS 允許我們使用 requirejs 去加載部分代碼。它也允許與其他解決方案一同工作,例如 webpack.
獲勝者:React
每個(gè)人都知道去掌握 Angular 的道路是崎嶇不平的:剛開始學(xué)的時(shí)候很容易,隨著你的深入學(xué)習(xí)會(huì)變得越來越困難,就好像婚姻一樣…
我們發(fā)現(xiàn),僅僅用一周的時(shí)間,你就可以把 React 學(xué)到一個(gè)很高的水平。想要習(xí)慣這單一的過程需要一些時(shí)間,特別是對(duì)網(wǎng)絡(luò)開發(fā)者,但是一旦你堅(jiān)持做了,就會(huì)變得簡(jiǎn)單起來。
Angular 的生存周期是復(fù)雜的,想要掌握它,你真的需要讀代碼。編譯和連接并不是靠直覺,一些特殊的情況可能讓人困惑不已(編譯時(shí)的循環(huán),指令間的沖突)。另一方面,React 僅僅擁有一些生存周期方式,并且它們可以自行解釋說明。據(jù)我們的了解,React 最好的特性就是從不,或者至多一次使得我們需要去讀它的代碼。
獲勝者:React
良好的抽象性是極其重要的。抽象性提供了快速的發(fā)展以及隱藏了那些對(duì)于開發(fā)者不需要查詢的詳細(xì)說明。
我們發(fā)現(xiàn) Angular 的抽象性是存在漏洞的。這表示為了使用它工作,你需要了解最根本的模型。這就是為什么大多數(shù)人在調(diào)試他們的代碼時(shí)需要修改 Angualr 的內(nèi)部結(jié)構(gòu)。
為了彌補(bǔ)這些漏洞,提出了一些概念,例如指令優(yōu)先級(jí)。但是當(dāng)我使用的指令來自三個(gè)不同的版本,我要如何控制優(yōu)先級(jí)?我為什么要關(guān)心優(yōu)先級(jí)呢?為什么不同的指令有時(shí)不能在相同的網(wǎng)頁代碼上良好地一同運(yùn)行?為什么我需要知道消化周期?
React 的抽象性表明它在一些地方是不太靈活的,例如不能在網(wǎng)絡(luò)標(biāo)簽中增加屬性,或者在組成部分中增加標(biāo)簽。這些都被 React 混合類的實(shí)現(xiàn)給解決了(混合類允許僅在生存周期內(nèi)重復(fù),并且有可預(yù)測(cè)的執(zhí)行命令),并且不存在漏洞(就像我上面提到的,我們從來不需要看它的代碼)。
獲勝者: React
通過模型的復(fù)雜性,我正在提及你所構(gòu)造的之后形成可視化的數(shù)據(jù)模型。
由于 copy-n-compare ,Angular 的性能在處理范圍內(nèi)是敏感的。這要求你不能使用大型的模型。關(guān)于這個(gè)有贊同者也有反對(duì)者。贊同者認(rèn)為它使得代碼更加簡(jiǎn)單并且可測(cè)試;但是反對(duì)者認(rèn)為它迫使你拆分你通常使用的東西,之后再重建它(以服務(wù)要求為例)。
React 讓你可以自由去選擇,不用考慮性能的優(yōu)先級(jí)。結(jié)果通常取決于你是否是一個(gè)優(yōu)秀的程序員。
獲勝者:不分高下
當(dāng)程序不運(yùn)行時(shí),我們總是開始繁瑣的調(diào)試工作。我將這個(gè)分解為兩個(gè)情況——認(rèn)識(shí)你的邏輯部分不運(yùn)行的原因,以及了解 HTML 伴隨著產(chǎn)生它的東西而輸出。
Angular 是一個(gè)被動(dòng)的事件系統(tǒng),它總是寫起來很容易,但當(dāng)堆棧軌跡結(jié)束比你預(yù)想的更長(zhǎng)以及不同時(shí),調(diào)試起來很困難。但是,Angular 在提供邏輯結(jié)構(gòu)方面做得十分出色,例如服務(wù)器。如果使用正確,它們使得代碼的測(cè)試和調(diào)試變得更加簡(jiǎn)單,但是任何優(yōu)秀的程序員都會(huì)試著將代碼和邏輯分離開。
當(dāng) Angular 的指令不運(yùn)行時(shí),一種選擇是用一種不同的方法來重寫代碼,因?yàn)橛腥绱硕嗟木幋a在運(yùn)行。另一個(gè)選擇還調(diào)試 Angular 的代碼——不是一個(gè)繁瑣的工作。
React 有兩個(gè)重要的情況——更新模型/由于用戶事件執(zhí)行其它動(dòng)作;單方面的翻譯掩蓋總是相同的部分。這表示只有相當(dāng)少的平臺(tái)來搜尋你的漏洞,并且堆棧軌跡在 React 的代碼和你自己的之間有很清晰的區(qū)別。它們通常不混合。React 也擁有很少的編碼,并且它集中在同一個(gè)地方——虛擬網(wǎng)絡(luò)的對(duì)比。它是一個(gè)暗箱,但在我們的經(jīng)驗(yàn)中,它總是如預(yù)期般工作。
當(dāng)談?wù)摰?HTML 的理解,以及代碼的回溯,結(jié)果是相反的。在 React 中,為了產(chǎn)生 HTML 是很那比較代碼的。甚至使用 jsx,當(dāng)“如果”和“重復(fù)”控制將HTML 碎片變成小塊樣本時(shí),你可能幾乎不比較它們。在 Angular 中,結(jié)果卻極其類似 HTML 的模板。
獲勝者:React
HTML:Angular
在 Angular 中,你僅僅可以綁定范圍。這說明,在復(fù)雜的情況下,例如綁定一個(gè)服務(wù)器/非同步服務(wù)器,或者當(dāng)綁定一個(gè)大型的模型時(shí),你需要有一個(gè)媒介模型,并且你需要處理消化周期以及明確時(shí)間。
對(duì)比而言,React 僅僅提供好的語法來綁定,這叫做價(jià)值鏈(“value” 性能和 “onChange” 性能的一個(gè)單一屬性)。這個(gè)概念很簡(jiǎn)單,它聽上去好像沒有工作,但實(shí)際它做了。并且如果你清楚地了解它后,你將能夠創(chuàng)照你自己的鏈接聲明或者相似的可以回復(fù)你所有綁定需求的功能。
獲勝者:React
React 控制自身功能十分簡(jiǎn)單。如果你進(jìn)行成分更新,你可以選擇你喜歡的對(duì)比關(guān)系——模型或者介紹。如果你的模型比較簡(jiǎn)單,只要讓 React 在虛擬網(wǎng)絡(luò)上做對(duì)比就行。如果你的模型很復(fù)雜,或者你創(chuàng)建了許多文檔模型,你可以用這個(gè)功能的實(shí)施習(xí)慣來優(yōu)化它,在這里你可以設(shè)計(jì)自己的臟查找原理,這是十分有效的。
在 Angular 中,你需要開始計(jì)數(shù)范圍(有許多可以為你所用的公共程式),在一些情況下,你僅僅需要在純粹的 js 中實(shí)施一個(gè)元件的內(nèi)部結(jié)構(gòu),并且為了便利用 Angular 包裹它。最有力的證據(jù)就是你能找到的關(guān)于 Angular 功能調(diào)整的文章的數(shù)量。
獲勝者: React
Angular 的優(yōu)點(diǎn)就在于它能夠把需要用到的所有資料全部準(zhǔn)備好。然而,由于命名空間和優(yōu)先級(jí)沖突的原因,我們并不需要從不止一個(gè)供應(yīng)商那里使用 Angular 函數(shù)庫。 React 能夠讓你用自己喜歡的方式管理它。也就是說, Angular 依舊占據(jù)很大的市場(chǎng),而且能提供更多現(xiàn)成的資料。
勝利者:不相高下
我將最重要的一個(gè)留到了最后…… 雖然絕大多數(shù)有關(guān) Angular 或者 React 的文章都在討論指令或者數(shù)據(jù)流,但現(xiàn)實(shí)是 80% 你所編寫的在線服務(wù)都是用戶界面。我把它們叫做面板,也就是應(yīng)用邏輯的構(gòu)件。它們包含了大量的信息流和制定流程,并被用于使用現(xiàn)成構(gòu)件。但通常面板并不是能夠被重復(fù)使用的,它們是我們的用戶能夠看見和接觸最多的部分。 React 對(duì)于這些來說不是較好的選擇。在編寫中繼器的時(shí)候,它會(huì)如下所示:
var createItem = function(itemText) {
return <li>{itemText}</li>;
};
return <ul>{this.props.items.map(createItem)}</ul>;
想要從類似的帖子中學(xué)到更多?訂閱了解更多!
而在 Angular 里如下圖:
<ul>
<li ng-repeat="item in items">{{item}}</li>
</ul>
想要從類似的帖子中學(xué)到更多?訂閱了解更多!
這樣有多好呢?(答案是:很多)因而,Angular 在這一部分的比較中是顯而易見的勝者。
勝利者:Angular
那么,我們?cè)趺唇鉀Q這場(chǎng)爭(zhēng)論呢?我們?nèi)绾卫煤蒙鲜?React 的所有優(yōu)點(diǎn),卻又并不遺漏 Angular 的最重要的特征呢?我們決定試一試來解決這個(gè)問題。
對(duì)于工具的設(shè)計(jì)考慮如下:
結(jié)果就是令人驚奇的 React 模版。我們獲得了 Angular 模版的優(yōu)勢(shì),同時(shí)擁有了 React 的簡(jiǎn)易!我們得到了表達(dá)與邏輯之間的完全分離,模版的聲明性編寫,并使它更有用。我們?cè)黾恿四J捷d入程序支持(AMD,或Common JS),以便于模版中其他組件的重復(fù)使用。讓我們用一些案例來看看它的簡(jiǎn)潔之處。
<ul>
<li ng-repeat="item in items">{{item}}</li>
</ul>
想要從類似的帖子中學(xué)到更多?訂閱了解更多!
注釋: 索引
來自于屬性名項(xiàng)目,被用來允許使用嵌套中繼器的目錄。
<label rt-if="this.hasError()">{this.getError()}</label>
想要從類似的帖子中學(xué)到更多?訂閱了解更多!
注釋:這是一個(gè)真實(shí)的IF
句, 意思是如果表達(dá)是假的,將完全不會(huì)渲染節(jié)點(diǎn)。
<div rt-scope="this.getUserDetails() as theUser" title="{theUser.loginName}">
Real Name: {theUser.firstName} {theUser.lastName}<br/>
Login: {theUser.loginName}
Last paid at: <span rt-class="{status:true, overdue:this.isUserOverdue(theUser)}">{theUser.lastPaid}</span>
</div>
想要從類似的帖子中學(xué)到更多?[訂閱了解更多!]()
注釋:因?yàn)橄胍3炙暮?jiǎn)潔性,我們已經(jīng)盡可能地不創(chuàng)造太多屬性。我們只添加了一些能夠創(chuàng)造價(jià)值的成分。
<div>{this.props.children}</div>
想要從類似的帖子中學(xué)到更多?訂閱了解更多!
注釋:真的很簡(jiǎn)單……
<div>
<div rt-repeat="task in tasks" style="font-weight:{task.selected ? 'bold' : 'normal' }" onClick="() => this.toggleTask(task)">{task.title}</div>
<button onClick="{this.save}">Save</button>
</div>
想要從類似的帖子中學(xué)到更多?[訂閱了解更多!]()
注釋:這是 React 模版最佳優(yōu)勢(shì)之一。我們生成了方法,這樣你就不需再向 DOM 或工作目錄中存儲(chǔ)任何東西。你可以只編寫邏輯代碼,繼續(xù)向你的目的研究。我們提供有2個(gè)選項(xiàng): lambda 表達(dá)式,或者如果{}符號(hào)被使用,它是一個(gè)可以返回函數(shù)指針的表達(dá)式。最終,以 camelCase 事件名為開始的常規(guī)操作,所對(duì)應(yīng)的常用屬性可以使用這兩種符號(hào)。
<rt-require dependency="./utils/translate" as="tr"/>
<rt-require dependency="./comps/colorPicker" as="colorPicker"/>
<form>
{tr('Enter_Your_Name')}: <input type="text" valueLink="{this.linkState('name')}"/><br/>
{tr('Choose_Favorite_Color')}: <colorPicker valueLink="{this.linkState('favColor')}"/>
</form>
想要從類似的帖子中學(xué)到更多?訂閱了解更多!
它的類型就相當(dāng)于在超文本語言中,這就意味著關(guān)鍵詞不必用駱駝拼寫法翻譯,(像是 React 框架中要求的),你可以像其他任何情況一樣用{}符號(hào)來插入語言,"class" 屬性也可用(不用將其稱呼為類別名稱或 className)
Angular 和React 兩種框架都很強(qiáng)大,我們很難在其中選擇一種去用 Angular 框架不會(huì)被改變,這就使得它在適合你的方案進(jìn)程的情況下變得很好用,React 框架可以讓你自由去改變并且很簡(jiǎn)單,但又缺少了 Angular 框架的規(guī)約力。然而,當(dāng)你使用 React 模板時(shí),你會(huì)用到 Angular 模板中受我們所喜歡的東西,同時(shí)又不會(huì)感覺到 Angular 模板中麻煩的東西。對(duì)于有復(fù)雜項(xiàng)目要設(shè)計(jì)的人,想要制作文件包的人,或是要用框架與其他庫進(jìn)行連接的人,我們認(rèn)為 React+React 模板共用是最好的選擇。
Amit Kaufman 是 Wix 的主編,資深開發(fā)者,管理者以及企業(yè)家。
更多IT技術(shù)干貨: wiki.jikexueyuan.com
加入極客星球翻譯團(tuán)隊(duì): http://wiki.jikexueyuan.com/project/wiki-editors-guidelines/translators.html版權(quán)聲明:
本譯文僅用于學(xué)習(xí)和交流目的。非商業(yè)轉(zhuǎn)載請(qǐng)注明譯者、出處,并保留文章在極客學(xué)院的完整鏈接
商業(yè)合作請(qǐng)聯(lián)系 wiki@jikexueyuan.com
原文地址:https://www.airpair.com/angularjs/posts/angular-vs-react-the-tie-breaker