Tech Log

프레임워크의 선택, React vs Angular

celina.7 2021. 6. 2. 12:53

시작하며

안녕하세요. 카카오엔터프라이즈 워크엔진셀에서 프론트엔드 개발을 담당하고 있는 데니스입니다.

저는 이번에 신규 프로젝트의 FE (Front-end) 개발을 혼자 진행하게 되었습니다. 혼자 개발을 하다 보면 자칫 외로운 싸움이 될 수 있는데, 혼자 개발하면서 고민한 부분들을 이렇게 정리하고 공유하면 재미있을 것 같다는 생각이 들어서 포스팅을 작성하게 되었습니다. 앞으로 제가 진행하고 있는 신규 프로젝트 개발 과정을 차례대로 소개할까 합니다.

 

혼자 프로젝트를 진행하면 기술 스택이나 여러 가지 컨벤션을 마음대로 정할 수 있다는 장점과 자유가 있지만, 이 프로젝트를 평생 혼자서만 개발하고 운영할 것은 아니기에 제가 선택한 것에 대한 명확한 이유가 있어야 하고 합리적인 기술 스택과 컨벤션을 정해야 한다고 생각하였습니다.

따라서 이번 프로젝트의 프레임워크와 기술 스택을 정할 때 어떤 고민을 했는지 여러분과 공유하고자 하는데요. 처음 홀로 개발하시게 된 개발자 분들께도 조금이나마 도움이 되길 바라며 글을 시작하겠습니다.

 

 


프론트 프레임워크

저는 사내에서 주로 Angular를 사용하고 있지만, 개인적으로 React를 더 선호하여 이 둘 중 하나를 선택하고자 하였고, 그 과정에서 고민한 부분들을 공유하고자 합니다.

[그림 1] React와 Angular 비교 (출처:altexsoft.com)

사실 React와 Angular 비교하는 글은 상당히 많이 존재하며 그만큼 다룰 내용도 많습니다. 둘 다 훌륭하기 때문에 상황이나 성향 등에 따라 프레임워크를 선택하게 될 것 같은데요. 이번 프로젝트에서 제가 주로 고려한 부분은 다음과 같습니다.

 

전반적 성능

먼저 짚고 넘어가야 할 부분이 있습니다. 아직도 많은 분들이 Angular는 느리다는 인식을 갖고 계신 것 같은데요. 그런데 속도 문제는 AnuglarJS(Angular1)에는 해당할 수 있지만, Angular(Angular2+)에는 해당하지 않습니다. 즉, Angular(Angular2+)는 React에 크게 뒤지지 않는 성능을 자랑합니다.

 

[그림 2] Performance (points 0-100)- higher is better (출처:medium.com)

 

위 차트는 Lighthouse Audit으로 측정한 프론트 프레임워크 성능을 나타낸 것인데요. AngularJS의 성능은 꽤 좋지 않은 것으로 측정되었지만, Angular의 성능은 React + Redux 보다 더 좋다는 것을 확인할 수 있습니다([그림 2]). 물론 Angular에 NGXS 같은 전역 상태 관리 라이브러리를 추가하여 측정하였다면 React + Redux와 거의 비슷할 것으로 예상됩니다.



[그림 3] Transfer size in KB - fewer is better (출처:medium.com)

 

위 차트는 Chrome network tab에서 확인한 전송 크기를 나타낸 것입니다. 전송 크기는 프레임워크 크기와 빌드 도구가 얼마나 더 작게 번들링하는지에 따라 달라집니다. 다들 예상하다시피 AngularJS의 전송 크기는 큰 편에 속하며 Angular는 React + Redux 보다 작은 전송 크기를 보여주고 있습니다([그림 3]).

 

만약 Angular가 이전 AngularJS의 성능이었다면 React와 비교하지 않았을 것입니다. 그래도 순수 React와 Angular의 성능을 비교하면 React가 조금 더 유리할 것으로 예상되지만, 현재 성능만으로 React를 선택할 만큼 큰 차이를 보여주고 있지 않다고 생각합니다. 

 

스토리북 사용성

스토리북(Storybook)은 프론트엔드 개발자가 아니라면 조금 생소할 수 있는 도구인데요. 간략하게 설명하자면 UI 컴포넌트를 독립적인 환경에서 실행하여 컴포넌트 단위로 공유할 수 있고 컴포넌트에 대한 문서화와 UI 테스팅까지 제공하는 오픈소스 도구입니다. 이를 통해 클라이언트를 실행하지 않고 작업하고 있는 마크업 UI를 확인할 수 있어서 마크업 개발자에게 상당히 유용한 도구라고 할 수 있습니다.

 

[그림 4] 스토리북 실행 화면 (출처:storybook.js.org)

 

그런데 React와 Angular는 스토리북을 사용하는 방법에서 조금 차이가 있습니다. 여기서 Angular의 모듈 의존성이 단점으로 드러났는데요. 간단한 Angular 예제 코드를 통해 살펴보도록 하겠습니다.

 

[예시 1] Angular 스토리북 코드

 

위 코드는 Angular에서 LNB 컴포넌트의 스토리북 코드를 간단하게 작성한 것입니다([예시 1]). 해당 컴포넌트에 종속되는 모듈과 자식 컴포넌트들을 위와 같이 명시적으로 추가해주어야 비로소 하나의 컴포넌트 스토리를 작성할 수 있습니다. 

모든 컴포넌트에 대응할 수 있는 moduleMetadata를 만들어 분리하는 것도 하나의 방법이지만 이 또한 유지보수 비용이 발생하게 되며 각 스토리에 불필요한 모듈들이 추가되어 스토리북 실행 시간이 증가하게 됩니다. 다음은 위와 동일한 역할을 수행하는 React 예제 코드를 살펴보도록 하겠습니다.

 

[예시 2] React 스토리북 코드

 

위 코드는 React에서 LNB 컴포넌트의 스토리북 코드로,  [예시 1]의 Angular보다 코드가 간결한 것을 볼 수 있습니다. 종속된 모듈이나 자식 컴포넌트들은 해당 컴포넌트에 이미 포함되어 있으므로 스토리북 코드에서 따로 선언할 필요 없이 LNB 컴포넌트만 Import하여 사용하면 됩니다.

프로젝트 전체 구조에서 Angular의 모듈 의존성은 명시적으로 연결고리를 나타내는 것 같아 신뢰도를 높일 수 있는 느낌을 받았지만, 컴포넌트 단위로 UI 확인이 목적인 스토리북과는 다소 어울리지 않다는 생각이 들었습니다. 따라서 스토리북 사용 측면에서는 React가 더 유리하다고 결론내렸습니다.

 

 

유닛 테스팅의 용이성

유닛 테스팅(Unit Testing)을 위한 테스트 코드를 작성하는 방법은 스토리북과 비슷한 맥락입니다. Angular의 경우 의존하는 모듈 및 자식 컴포넌트들을 명시해야 하는 반면, React는 해당 컴포넌트만 Import하여 사용하면 됩니다. CLI를 통해 컴포넌트를 생성할 때 자동으로 만들어지는 테스트 코드를 살펴보도록 하겠습니다.

 

[예시 3] Angular 유닛 테스팅 코드

 

위 코드는 Angular에서 자동 생성된 테스트 코드에서 필요 모듈들을 묶어 놓은 requiredModules를 추가한 모습입니다([예시 3]). requiredModules는 모든 컴포넌트에 대응할 수 있도록 모듈들을 묶어놓았기 때문에 테스트할 때 불필요한 모듈도 포함되어 있을 수 있고,  따라서 그만큼 유닛 테스팅 시간이 길어지게 됩니다. 사실 스토리북의 실행 시간은 그다지 중요하게 느껴지지 않았지만, 유닛 테스팅 시간이 길어지는 것은 조금 부담으로 느껴졌습니다.

 

[예시 4] React 유닛 테스팅 코드

 

위 코드는 React에서 자동 생성된 테스트 코드입니다([예시 4]). Angular와 달리 따로 코드를 추가하지 않아도 테스트를 통과하는 것을 볼 수 있습니다. 해당 컴포넌트만 선언하면 되기 때문에 Angular보다 테스팅 시간도 비교적 짧았습니다. Angular는 모듈 의존성 때문에 독립적인 환경을 구축해야 하는 스토리북이나 유닛 테스팅에서 불리한 것을 볼 수 있었습니다. 저는 이러한 Angular의 모듈 의존성 때문에 React에 더 매력을 느꼈던 것 같습니다.

 

마크업 개발자와의 협업

마크업 개발자와의 협업도 반드시 고려해야 할 사항이었습니다. Angular에서는 일반적으로 HTML, SCSS, TS 파일을 따로 분리하여 컴포넌트를 개발합니다. 반면 React는 JSX 문법과 Styled Components 라이브러리를 사용하여 오직 Javascript만으로 컴포넌트를 개발하는 것이 대세가 되어가고 있습니다. 따라서 상대적으로 Angular가 마크업 개발자와 협업하기에는 더 유리하다고 생각하였고, 이는 Angular의 장점임에 틀림이 없습니다.

하지만 React에서 이 부분만 보완한다면 선택의 고민을 끝낼 수 있을 것 같다는 생각이 들었습니다. 그래서 저는 고민 끝에 React에서 VAC(View Asset Component)라는 패턴을 적용하게 되었습니다. VAC(View Asset Component)는 다소 생소할 수 있는 개념이지만 매우 간단한 패턴입니다.

 

[그림 5] 일반적인 패턴과 VAC 패턴 비교 (출처:npm.io)

 

HTML과 거의 유사한 뷰(View) 컴포넌트와 비즈니스 로직(Business Logic)만 담고 있는 컴포넌트를 만드는 것으로 역할을 완전히 분리하는 것입니다. 흔히 알고 있는 Presentational 컴포넌트와 Container 컴포넌트 관계처럼 보이지만 VAC 패턴에서는 모든 컴포넌트를 뷰 파일과 로직 파일로 분리한다는 것이 특징입니다. 다음은 VAC 패턴을 적용한 간단한 예시입니다.

 

[예시 5] Directory Structure

 

[예시 6] View Component
[예시 7] Business Logic Component

 

위와 같이 모든 컴포넌트는 뷰 컴포넌트와 비즈니스 로직 컴포넌트 쌍으로 존재하게 됩니다. 이로써 React에서도 마크업 개발자는 HTML을 개발하듯이 뷰에 집중할 수 있고 프론트엔드 개발자는 비즈니스 로직에 집중할 수 있습니다.

 

 


마치며

저는 프론트 프레임워크의 선정에 있어 많은 고민 끝에 Angular 대신 React를 선정하게 되었는데요.  Angular의 성능은 React와 비교해도 부족함이 없고 Angular에서 통상적으로 HTML, SCSS를 이용하여 컴포넌트를 구성하기 때문에 마크업 개발자와 협업이 유리한 편입니다. 그럼에도 불구하고  제가 맡은 신규 프로젝트에 Angular가 아닌 React를 사용하게 된 이유와 React에서 마크업 개발자와 협업을 유리하게 가져가기 위한 VAC 패턴을 적용하기 까지의 과정을 간략하게 살펴보았습니다.

앞으로 계속해서 제가 프로젝트를 진행하면서 기술적으로 어려웠던 부분이나 흥미로운 부분들을 공유하고자 합니다. 이 포스팅이 그 전설의 시작이 될지도 모르겠네요. 앞으로도 많은 관심 부탁드리며, 포스팅 작성에 도움을 주신 Rama에게 감사드립니다.

 

 

참고 문헌

[1] React Angular 비교 (https://www.altexsoft.com/blog/engineering/react-vs-angular-compared-which-one-suits-your-project-better)

[2] A RealWorld Comparison of Front-End Frameworks 2020 (https://medium.com/dailyjs/a-realworld-comparison-of-front-end-frameworks-2020-4e50655fe4c1)

[3] 스토리북 실행 화면 (https://storybook.js.org)

[4] react-vac v0.1.0 (https://npm.io/package/react-vac)

 

Denis (배형진)

어제보다 더 나은 코드를 작성하기 위해 노력하는 프론트엔드 개발자입니다.