React vs Angular 2: melyiket válasszam?
Néhány szempont mentén végigvettük a két fejlesztői keretrendszer lényeges különbségeit, hogy könnyebb legyen eldönteni: melyiket érdemes egy-egy webes-mobilos projekthez bevetni?
Írtunk már részletesebb bemutatót mindkét felfutóban lévő webes-mobilos fejlesztői keretrendszerről, a Reactról és az Angular 2-ről is. Itt az ideje, hogy a két szereplőt egymással is összevessük, néhány releváns dimenzió mentén - melyiket mire érdemes inkább használni, és mire kell figyelni a kiválasztásnál.
Filozófia, megközelítés, fókusz
A bőség zavara - így jellemezhetnénk a JavaScript-ökoszisztéma egyik legnagyobb hátulütőjét. Ma már hihetetlen számú keretrendszer és egyéb fejlesztői eszköz áll rendelkezésre, amelyek között nagyon nehéz megtalálni az ideálisat az adott célra - és ha sikerül is, a következő projekthez szinte biztosan egy új frameworköt kell majd megtanulni.
Az Angular 2 elébe megy ennek a problémának, egy olyan kiterjedt, általános keretrendszer ez, amely igazi mindenes szeretne lenni. Ennek előnye, hogy rengeteg különböző problémára tud megoldást kínálni a beépített készletből, így nem kell a keresgéléssel bajlódni. A nagyon speciális problémákra pedig az ökoszisztémából lehet jó minőségű megoldásokat behúzni, tehát azért marad szerencsére választási lehetőség is - ott, ahol erre tényleg szükség van.
A függőségek kezelése és a tesztelés csak az első lépés, a keretrendszer natívan támogatja a reaktív programozást, abba beépült az RxJS, és erőteljesen épít az observable és immutable objektumokra is - ezekre később visszatérünk. A keretrendszerhez saját Redux-implementáció is tartozik (az ngrx/store), és ugyan nem az alapcsomag része, de az Angular-fejlesztők terméke ez is.
Az Angular hozzáállásának persze két komoly hátránya is van. Egyrészt mindenről megvan a saját "véleménye", tehát adott problémára igen ajánlott az alapértelmezett megoldást használni. Ha mégsem arra, vagy nem abban a formában van szükség, akkor az árral szemben úszásnak komoly szenvedés lehet a vége - csúnya hackelésbe torkollhat a dolog.
Lássuk, hogyan más ez a React esetében? A React nem egy általános keretrendszer, hanem egy könyvtár, amely kizárólag a view rétegre fókuszál. Ez ugyanis a Reactot fejlesztő Facebook szerint a magas minőségű webes alkalmazások fejlesztésének és építésének alapja. A React architektúrájában egyébként kicsit a Unix-filozófia érvényesül, apró, könnyen összeilleszthető építőkockákból áll, számos területre pedig saját kódkönyvtárat választhat magának a fejlesztő - emiatt jóval nagyobb a mozgástér.
Két ilyen kiegészítő könyvtár magasan kiemelkedik egyébként a mezőnyből és emiatt informálisan akár a React-ökoszisztéma alapelemeinek is lehet tekinteni. Az egyik a Dan Abramov-féle Redux, és a React Router. Előbbi az alapvető állapotkezelést adja és támogatja az egyirányú adatfolyamot, jelentősen egyszerűsítve az alkalmazás logikáját. Utóbbi pedig a webapp állapotát és az URL-t tartja szinkronban, hogy az adott címen mindig az UI-nak ugyanazt az állapotát találjuk.
A React hatalmas előnye, hogy még e két kiegészítővel együtt is nagyon kis méretű - köszönhetően annak, hogy egyetlen területre fókuszál, így a kliensoldali letöltés nagyon gyorsan lezajlik, ami nem elhanyagolható tényező. Ezzel együtt tetszőlegesen bővíthető, a különböző modulok zavarba ejtő választékával lehet tuningolni a Reactet - de ezzel vissza is értünk az eredeti problémához.
Mi zajlik a háttérben?
A React és az Angular is az összes létező platformot szeretné lefedni, és mindkettő a webről indul a hódító útra a mobil, a PC-k, a TV, a VR és minden elképzelhető irányba. De a felszínes hasonlóság mögött komoly architekturális különbségek vannak, amely a platformok lefedésében is komoly hatással van - az Angular 2 a Reacttal ellentétben nem Virtual DOM-ot használ (ezt tévesen is írtam az eredeti cikkben), helyette az Angular 1.x-hez hasonló változásdetektálás (change detection) működik, igaz, alaposan továbbfejlesztet formában.
Az első jelentős újdonság, hogy az Angular 2-ben alapból nincsenek már kétirányú adatkötések (data binding), a változásdetektáláshoz a UI komponensekből irányított fa épül, nem pedig gráf, mint eddig. Ezt a teljes fát pedig a gyökértől a levelekig járja be a rendszer, algoritmusa pedig kiszámíthatóbb és gyorsabb, különösen a nagyobb struktúrák esetében.
Az persze továbbra sem ideális, hogy a teljes fát be kell járni, így az Angular fejlesztői sem álltak meg ezen a ponton, az Angular 2 alkalmazások ténylegesen reaktív rendszerek lesznek. Az immutable objektumok használata például azt jelenti, hogy jelentős részfákat ki lehet zárni a bejárásból, az observable típusú objektumok esetében pedig eseményvezérelt a frissítés, így amíg ez nem következik be, ezek a részfák is kimaradnak.
Ezen túl pedig segít a web worker szálak használata, amely lehetővé teszi, hogy a UI illetve az alkalmazás belső logikája külön szálakon fusson. Ez nagyon hasonló ahhoz, ahogy a natív mobilalkalmazások működnek, és előnye is pontosan ugyanaz: folyamatosabb, jobb teljesítményt nyújtó UI. Az Angular 2-ben megvalósított változásdetektálásról errefelé érdemes tovább olvasni.
Az Angular 2 minden esetben így működik, ahol DOM-manipuláció zajlik, így a Cordova, Ionic és az Electron frameworkök esetében is. Kivétel is van, a NativeScript esetében a szálkezelés nagyon hasonló, viszont ott a natív kód előtt van egy köztes réteg, amely a JavaScript hívásokat a natív API-ra fordítja - ehhez pedig nem használ semmilyen wrappert, így az idegen szintaktikát kell használni, ami kicsit szokatlanná teszi.
Ezzel szemben a React egy általánosabb megoldással operál, az összes view változást a Virtual DOM mögé rejti - ami futhat a böngésző DOM-ján vagy a React Native esetében natív komponenseken is. Erről részletesebben az előző cikkben írtunk, azt érdemes újra fellapozni.
Lássuk, miben különbözik a két keretrendszer natív appok készítéséhez használható komponense, a NativeScript és a React Native. A NativeScript esetében (ahogy már említettük) sokkal közvetlenebb a hozzáférés a rendszer saját natív API-jához, vagyis sokkal inkább megköveteli a gazdarendszer ismeretét. Ezzel szemben a React Native megőrzi a JavaScript szintaktikát, nem kell tehát ezzel a kettősséggel foglalkozni. A felület programozása is eltér: a NativeScriptnél a UI-t egy XML írja le, a React Native esetében marad a már sokak által ismerősként kezelt JSX.
Nyelvek
Az Angular 2 hangsúlyt fektet a különböző nyelvek szétválasztására, elválik a HTML, a CSS és a Script-nyelvek, külön fájlokban a megszokott elemek. Ez azonban hozzáadott komplexitást jelent, a különböző sablonokat és összekötéseket nehezebb átlátni és követni, illetve sokszor a hibák csak futás során jönnek ki.
Az Angular 2 már TypeScriptben készül, és természetesen támogatja is a TypeScript nyelv használatát. Ennek legfontosabb előnye a típusok használata, így biztonságosabban lehet programozni benne. Emellett viszont tökéletesen működik JavaScript 5 és 6, illetve a Google-féle Dart nyelvekkel is.
A React ezzel szemben teljesen JavaScript-központú, és az alkalmazást egyetlen állományban tárolja, ami elsőre kissé ijesztő lehet. Nagy előnye viszont, hogy egyszerű és átlátható a rendering logika, amely fölött a fejlesztőnek teljes kontrollja is van. Fontos, hogy a JSX-hibák még fordításidőben kiderülnek, nem kell komplex teszteket futtatni ehhez. További előny, hogy a Reduxot és az egyirányú adatfolyamokat használva nagyon erős programozási mintákat kaphatunk, jól tagolt felelősségekkel az egyes programrészek között.
Annak ellenére nem kell lemondani a típusosságról, hogy "sima" JavaScriptet használunk: a Flow ugyanis képes statikus típusellenőrzésre, és beépíthető a forráskódba különösebb erőfeszítés nélkül. De van alternatíva is, a React támogatja a TypeScriptet/TSX-et is - ez utóbbit érdemes megfontolni, elég sok példakód elérhető, viszonylag könnyen tanulható.
Érettség
Az Angular 2 ellen szól jelenleg, hogy a fejlesztés még mindig csak a kiadásra jelölt verziónál tart, nemrég érkezett az RC1. De közel van már a stabil kiadás, a ma elérhető verzió és a stabil között pedig már nem lesz érdemi változás, az API stabil, a fejlesztők inkább a bugokat vadásszák. Emiatt fejlesztésre az Angular 2 már most is befogható, a kiadással azonban érdemes megvárni a keretrendszer saját stabil kiadását. A React ezzel szemben már meglehetősen érett és kiszámítható, nem kell attól tartani, hogy hirtelen valami alapvető változik meg, és komolyabb bugokba sem lehet már nagyon belefutni.
Fordul azonban a kocka, ha a natív modult nézzük. A NativeScript ugyanis valamivel kiforrottabb fejlesztésnek számít, mint a nemrég rajtolt React Native, ennek megfelelően éles bevetésre is alkalmasabb az előbbi.
Fejlesztői eszköztár
Na itt érdemi különbség már nincs, mint az Angular 2, mind a React köré komoly és mély ökoszisztéma épül, így fejlesztői eszközökben egészen biztosan nem lesz hiány. Ettől még a két keretrendszer nem identikus, a fejlesztés menetében lesznek különbségek: az Angular 2 esetében a sablonokban (template-ek) vétett hibák csak futás közben jönnek ki, ami alattomosabb, és a fejlesztést is lassítja.
Ez a keretrendszer azonban támogatja a webes komponensek (web components) szabványát, legalábbis azok jelenleg elérhető, nem teljes verzióját. Ez azt jelenti, hogy ha a jövőben más keretrendszerre állnánk át, ezek a komponensek elvben tovább használhatóak maradnak. További előny lehet, hogy az Angular 2 fejlesztésében a Microsoft és a Google is nagyon aktív szerepet vállal, emiatt várhatóan a böngészők és a keretrendszer fejlesztése nem is válik majd el.
Támogatás, dokumentáció, dogfooding
Mind a Google, mind a Facebook nagyon aktívan használja saját keretrendszerét házon belül, hatalmas fejlesztőcsapatok dolgoznak ezekkel. Ennek megfelelően hosszabb távon is számítani lehet támogatásra, az elérhető dokumentáció pedig abszolút elsőrangú. Az Angular 2 előnye lehet később, ha a Google és a Microsoft ráállítja erre a platformra az evangelista-csapatot, így a helyi közösségekben is "arcot" kap a keretrendszer. Erre a Facebooknak nincs erőforrása, így annak elég kicsi az esélye, hogy mondjuk a React hivatalos-félhivatalos képviselőjétől a budapesti meetupokon lehessen kérdezni.
Ünnepi mix a bértranszparenciától a kódoló vezetőkig Négy IT karrierrel kapcsolatos, érdekes témát csomagoltunk a karácsonyfa alá.
A React mellett szólhat azonban, hogy a Facebook "erre tette fel a házat", vagyis míg a Google-Microsoft háza táján vannak még alternatív fejlesztési keretrendszerek, amelyek házon belül versenyeznek az Angularral, a Facebook kimondottan a React fejlesztésére fókuszál. Emiatt a React olyan stratégiai fontossággal bír a cég számára, ami az Angular esetében nem érezhető ennyire.
Konklúzió
Nem érdemes egyik vagy másik keretrendszer mellett pálcát törni, várhatóan mindkettő sikeres, hatékony és jó eszköz lesz (és persze még a duón kívül tucatnyi más megoldásra elmondható ez). Emiatt a döntés erősen személyes preferencia, illetve kontextus függvénye. Ha személyes vélemény kell: jelenleg inkább a React mellett tenném le a voksom annak érettsége, kisebb mérete, a JSX és a Redux miatt.
A cikk szerzője Orosz Gábor, a Budapest Mobile fejlesztői Facebook-csoportalapítója, szabadúszó fejlesztő.