티스토리 뷰

Angular

Angular 2 : 어디까지 왔을까

한장현 2016. 11. 5. 16:21

 안녕하세요~ 한장현입니다.


 이번에 좋은 기회가 생겨서 GDG DevFest Seoul 2016에 스피커로 참여하게 되었습니다.

 발표자료를 만드느라 블로그는 잠시 미뤄뒀었고... 내용 정리를 위해 발표 자료로 글 작성해봅니다 ㅎ


 Angular2가 어디까지 진행되고 있고, 프로젝트에 도입할 만 한 정도까지 왔는지 살펴봅니다.






Ver. 2.2.0


 2016. 11. 3 일자 기준으로 최신 버전은 2.2.0 입니다. npm에는 아직 2.1.2이 올라와 있지만 Angular 2 github에서는 2.2.0 버전을 확인할 수 있습니다. 공식 사이트 QuickStart에는 2.1.1을 기준으로 package.json이 작성되어 있네요.




 Angular 2가 final 버전을 달 때쯤 해서 Angular 2는 SemVer를 도입한다고 발표했습니다. SemVer에 대해서는 이전 포스팅에서 언급한 적이 있지만 다시 한 번 정리해보면, 버전 체계를 Major, Minor, Patch의 형식으로 맞춰서 의존성에 대한 판단을 명확하게 하기 제안입니다.

 하지만 Angular 2는 SemVer를 엄격하게 따르지는 않습니다. 2.1.x 버전과 2.2.x 버전이 병렬로 진행되고 있어서 더 정신없기도 하고, Patch 자리 이후에 추가 버전을 기재하는 일이 많네요. 그래도 기본 틀은 SemVer를 따라가려고 하는 모습을 보이고 있습니다.


 이제 Angular 2를 접할 때 겪을 수 있는 장애물들에 대해 살펴봅니다.



장애물 ① : 빠르고 지속적인 큰 변화


 Angular 2는 버전업이 굉장히 빠른 속도로 진행되고 있습니다. SemVer를 기준으로 보면 2.0.0 이후로는 Minor에 해당하는 버전업이 한 달이 채 안가고 있습니다. Patch까지 하면 거의 일주일에 한 번씩 새로운 버전이 발표되고 있습니다. 프로젝트에서 도입할 때 버전을 확정하려고 해도 버전이 너무 자주 바뀌니까 어려움이 있겠네요.

 빠르게 발전하고 있고 새로운 기능이 추가되는 것은 물론 환영할 일입니다. 그런데 CHANGELOG.md에서 Breaking Changes를 조심해서 볼 필요가 있습니다. Bug fixes 나 Features로 추가되는 것 이외에 크게 변한 부분에 대해서 설명을 하고 있는데, 이 부분은 Angular CLI의 등장이나 ngModule과 같이, 개발 방식을 크게 뒤집는 업데이트가 해당됩니다. 빠르고 지속적인 것은 좋지만 변화라는 것이 문제네요.

 Angular CLI가 발표되면서 프로젝트의 기본틀이나 컴포넌트를 만드는 방식, 테스트하고 서버를 띄우는 방식이 전부 바뀌게 됩니다. CLI가 모두 커버하고 있기 때문이죠.

 ngModule이 업데이트 되면서는 컴포넌트 구성에 대한 방식이 바뀌게 됩니다. 반복적인 코어 컴포넌트를 모듈로 묶어서 모듈 자체를 사용하는 방식으로 변경되었습니다. 공식 사이트의 QuickStart에서도 ngModule을 사용하는 예제를 볼 수 있습니다. ngModule을 안 써도 개발은 가능하지만, 좋은 기능이 있는데 굳이 안 쓸 필요는 없겠죠 ㅎ ngModule은 뒷부분에서 다시 설명합니다.

 이렇게 Breaking Changes에 해당하는 내용으로 Angular 2 개발 방식이 빠르게 바뀌면서 일부 책은 출판 일자를 연기하기도 했습니다.


장애물 ② : 새로운 개발 언어

 처음 Angular 2를 접하면 일단 만나는 진입 장벽은 "TypeScript를 꼭 써야 하는 것인지" 일 것입니다.

 Angular 2는 공식적으로 3가지의 개발 언어를 지원합니다. JavaScript, TypeScript 외에 최근에 Dart도 공식 지원 부서가 생기고 QuickStart도 지원되기 시작했습니다. 공식 사이트에서 이 내용을 확인할 수 있고, JavaScript보다 TypeScript가 위에 있는 것으로 보면, TypeScript를 더 밀고 싶은 것 같기도 하네요 ㅎ



 공식 사이트 주소 체계를 봐도 TypeScript, JavaScript, Dart는 동등한 레벨로 공식 가이드가 제공되고 있습니다.


 원래 Angular 2의 처음 시작은 AtScript였습니다. Angular 2를 처음 발표할 때도 AtScript라는 언어로 소개했죠. 구글에서는 ES5를 기반으로 ES6 확장분, TypeScript 확장분, Annotation 까지 추가한 스펙으로 개발하던 언어였지만, Microsoft에서 밀던 TypeScript와 통합하여 TypeScript 1.5버전 이후에는 Angular 2의 공식 언어로 TypeScript를 사용하고 있습니다.



 문제는 TypeScript를 사용하는 것 자체인데... ES5를 기반으로 타입과 어노테이션(@)에 대한 문법이 추가되었으니 JavaScript를 그대로 사용하는 것과 크게 다르지 않다는 의견도 있지만, 아무래도 거부감이 드는 것은 사실입니다. 문법이 달라지는 부분이 분명히 존재하고, 아직까지는 TypeScript 자체를 지원하는 브라우저가 없으니 TypeScript를 JavaScript로 변환하는 라이브러리도 사용해야 합니다. 개발 과정에서도 테스팅이나 번들링과 같은 라이브러리를 사용하기 위해서는 변환하는 한 단계를 더 거쳐야 하죠.


 여기에 최근에는 Dart마저 공식 지원 언어로 추가되었습니다. TypeScript만 해도 써야할 지 고민인데 Dart라니... Dart도 TypeScript와 문법이 비슷하며 컴파일하면 JavaScript 파일이 되는 언어입니다.

 AngularJS 1를 만들었던 Misko Hevery도 Angular 2 Dart에 대해 언급한 내용이 있습니다.

 Angular 2와 AngularDart는 동시에 진행되고 있었고, AngularDart에서 얻은 경험은 Angular v2에 적용되고 있다는 내용인데, 좀 더 나은 결과물을 위해 TypeScript와 Dart를 동시에 진행하는 것 같습니다.

 ng-conf 2016에서 발표된 자료를 보면 TypeScript를 기본으로 하는 것 같지만 Dart도 함께 진행되는 것을 확인할 수 있습니다.


 구글 트렌드를 보면 Angular 2가 정식 버전이 나오면서 TypeScript에 대한 관심도 증가하고 있습니다. Dart는 상대적으로 아직은 관심을 받지 못하고 있네요.


 그럼 이렇게 Angular 2가 공식 지원하는 TypeScript나 Dart를 쓰는 것과 JavaScript를 그냥 쓰는 것은 어떤 차이가 있을까. JavaScript 말고 다른 언어를 사용하는 장점이 있는 것인지 확인을 해보고 싶었습니다.



 각각의 언어로 컴포넌트를 만드는 코드입니다. TypeScript와 Dart는 비슷하지만 import 구문에서 ES6 스펙을 따르는 TypeScript와는 달리, Dart에서는 조금 다른 방식을 사용합니다. 많이 비슷하네요.

 JavaScript에서는 Annotation에 대한 부분을 보완하기 위해 app에 대한 객체에 AppComponent를 구겨 넣는 느낌입니다....

 개인적으로 JavaScript의 자유분방함을 좋아하지만, 문법의 간결함은 TypeScript나 Dart가 더 좋아보입니다.


 Angular 2를 사용하기 위해 부트스트랩하는 코드도 비교해 봅시다. JavaScript로 변환된 코드는 라이브러리에서 알아서 할 테니 각각의 언어에서 정의하는 방법만 살펴봅니다. TypeScript나 Dart는 큰 어려움 없이 "부트스트랩을 하고 있구나" 알아볼 수 있습니다.

 아... JavaScript에서는 이벤트 리스너를 추가하는 함수 안에서 ng로 시작되는 상당히 어색한 부분이 있네요... 이 부분은 한 번 작성하면 다시 안 볼 것 같지만 역시나 JavaScript의 형식으로 구겨 넣은 느낌입니다.


 TypeScript나 Dart의 언어 자체에 대한 장점은 JavaScript에서는 따로 신경써야 하는 부분이니 그것에 대한 내용은 제쳐두더라도, 코드의 가독성 측면에서 Angular 2개발 만큼은 JavaScript를 사용하고 싶지 않게 하네요.... TypeScript를 배워야 할 필요성을 느끼는 부분입니다.



장애물 ③ : 새로운 툴, 개발 방식의 변화

 Angular 2.0.0-rc.5 버전부터 Angular CLI가 등장하면서 Angular 2의 개발방식이 크게 변화합니다. Angular CLI contributor인 Mike Brocchi는 이전에 트위터에서 Angular 2를 접하는 데에 가장 큰 어려움이 무엇인지 물어본 적이 있습니다.

 가장 큰 어려움은 35%로 다른 프레임워크에 대한 관심이었습니다. React나 Ember, Vue.js가 더 좋다고 생각하기 때문에 Angular 2는 별로 관심이 없다는 응답이네요. 이전에 언급한 것처럼 Angular 2가 여전히 크게, 빠르게 바뀌고 있는 것도 프레임웍 자체에 관심을 떨어뜨리게 하는 요인이 될 것 같습니다. 이 통계에서 이야기 하고 싶은 것은, 역시 환경 설정이나 프로젝트 관리가 복잡하다는 것입니다. 새 프로젝트를 시작하면 환경을 설정하고, 폴더 구조를 잡고, 테스트는 어떻게 할 것이며, 빌드와 배포는 어떻게 할 것인지까지 틀을 잡는 것은 역시 어려운 일이죠. 하루를 온전히 설정만으로 보냈던 적도 있었습니다.

 이제 Angular CLI가 등장합니다. 기본 틀을 잡고, 컴포넌트를 추가하거나, 빌드 설정, 유닛/엔드투엔드 테스트, 서버 구동과 배포까지 Angular CLI가 모두 커버합니다. 기존에 여러 툴을 사용했던 것이 모두 Angular CLI로 통합되는 거죠.


 무엇보다도, 프로젝트의 기본 틀을 잡아주고, 컴포넌트가 추가될 때마다 기본 틀에 맞게 템플릿, 스타일, 테스트 케이스까지 함께 생성해주는 것은 정말 훌륭했습니다. 팀에서 특별히 폴더 구조에 대한 체계를 만들지 않았다고 해도 CLI 자체에서 체계를 잡아줍니다. 서버를 띄워서 프론트엔드 화면을 바로 확인할 수 있는 점도 좋네요. 백엔드를 제외한 Angular 프로그램 자체를 GitHub에 배포할 일이 많을지는 모르겠습니다만, GitHub에 배포하는 것도 CLI 명령어로 수행할 수 있습니다.


 CLI가 나온지 얼마 안되었고, 베타버전이므로 아직은 익숙하지 않지만, Angular 2를 개발하면서 CLI 사용은 필수가 될 것 같습니다.


작은 장애물 : 문법의 변화

 Angular 1을 이미 경험해봤다면 Angular 2를 접하는 데에는 큰 도움이 됩니다. 기본 철학은 그대로 가져왔기 때문이죠. 다만, 문법이 변한 부분이 좀 있습니다. 컴포넌트를 생성하는 방식이나 데이터 바인딩 방식이 변했습니다.


 Angular 2는 표준을 따르려고 노력하고 있으며 "컴포넌트"를 강조하고 있습니다. 상대적으로 Angular 1에 있었던 디렉티브가 없어지는 느낌이 들기도 하는데, Angular 2에도 역시 디렉티브는 존재합니다. 문법은 조금 달라졌지만...

 Angular 2 디렉티브 자체를 이야기하려는 것이 아니니, 어노테이션 방식으로 문법이 바뀌었다는 점만 언급하고 넘어갑니다.



 데이터 바인딩과 관련해서도 모든 부분에 2-way 바인딩을 사용하지는 않습니다. Angular 1과 다르게 2에서는 기본적으로 1-way 바인딩을 사용합니다. 기본 이중 중괄호는 단방향으로 바인딩되고, 컴포넌트에 있는 값을 DOM에 매핑하기 위해, DOM에서 발생한 이벤트를 컴포넌트에 전달하는 것도 단방향으로 바인딩됩니다. Angular 1에서 편리하긴 했지만 과도하게 2-way 바인딩을 사용하면 성능에 큰 문제를 끼쳤기 때문에 되도록이면 2-way 바인딩을 자제하는 느낌입니다.

 방향에 따라 기호가 다르니 구분은 가지만, 방식을 이해하는 데에는 이해가 필요합니다.


 템플릿에서 많이 사용하던 문법도 일부 변경되었습니다.

 ng-if, ng-repeat, ng-switch의 문법은 *를 사용하는 방식으로 변경되었습니다. Angular 2 템플릿에서 일부 내장 디렉티브에 대한 가독성을 높이기 위해 도입되었습니다. *를 쓴다는 것 이외에 크게 바뀌진 않았네요.


 Angular 2 진행 과정에서 최근에 가장 크게 변한 부분은 역시 ngModule이 추가된 부분입니다. CLI는 개발에 도움을 주는 툴이고 안쓰면 귀찮긴 하겠지만 개발 코드의 구조 자체에 영향을 주는 것은 아니었습니다. Angular 2.0.0-rc.5버전에서 ngModule이 추가되면서 코드의 구조에 직접적인 영향을 주게 됩니다.

 ngModule이 나오기 전까지 Angular 2에서는 DOM에 반영되는 마지막 단계의 객체는 Component 였습니다. Component 선언에서 selector를 지정하고 지정된 템플릿으로 맵핑되는 구조였죠. 이 방식은 Angular 1이나 ES6의 철학을 따르기 때문에 이해하기는 어렵지 않았습니다.

 문제는, 비슷한 컴포넌트를 만들 때 컴포넌트 선언과 import 문장이 반복된다는 것이었습니다. 예를 들면, 몇 단계의 인풋 폼을 구성할 때 폼 양식은 조금씩 다르지만 큰 기능은 비슷한 경우가 있습니다. 이런 경우에 폼을 구분해서 생성하면 의존성 주입에 같은 코드가 계속 들어갑니다.

 ngModule은 기능이 비슷한 모듈을 묶을 수 있습니다. 반복되는 인풋박스를 제어하는 코드와 함께 폼 자체를 모듈로 만들면 코어 모듈을 그대로 사용하는 것보다 폼을 통째로 가져다 사용하는 것이 편하겠죠.

 의존성 측면에서도 장점이 있는데, 컴포넌트를 구성할 때 const 로 선언되는(Angular core 기준) 디렉티브를 직접 export하는 방식과 달리 ngModule은 어노테이션 방식으로 선언되어 lazy loading을 가능하게 합니다. 이 방식은 초기 로딩 성능에도 영향을 줍니다.


 ngModule이 도입된 지 얼마 되지 않았기 때문에 사용방도에 대해서는 좀 더 사용자들의 경험이 필요할 것으로 보입니다. 간단하게 요약하면, 반복된 컴포넌트로 HTML 엘리먼트를 구성할 때 ngModule을 사용할 수 있습니다.



장점 ① : 속도

 Angular 2가 ng-conf 2015에서 어느 정도 모습을 갖춘 데모로 발표되었을 때 페이지 로딩 성능은 월등히 개선된 것으로 보였습니다. 이전까지는 Angular 1과 React를 같이 사용하는 것이 최적의 성능을 뽑아낸다고 알려져 있었지만, 데모에서 Angular 2 자체의 성능은 이것보다도 빨랐죠. 관객들이 환호를 보내는 장면이 인상깊었습니다.

 하지만 이 데모에는 문제가 있었습니다. Angular 1 + React 의 코드에 지연 시간이 500ms 지정되어 있었고 Angular 2에는 0ms 로 지정되어 있어서, 제대로 된 비교가 되지 않았습니다. 이후에 YouTube를 통해서 이 부분이 잘못되었음을 알리고 다시 비교를 수행했는데 이 때는 비슷하지만 Angular 2가 약간 빠른 속도로 확인되었습니다.


 Angular 1과 비교하면, zone.js에 의한 새로운 change detection 방식과 lazy loading, server-side rendering 등의 기술을 도입하면서 1 대비, 첫 로딩은 2.5배, 리렌더링은 4.2배, 성능 개선 후에는 언제나 5배 이상의 속도 개선을 보장한다고 합니다.

 정말이라면 정말 놀라운 개선이겠습니다만... 이 비교는 시기에 따라 맞기도 하고 아닐 수도 있습니다.

 Angular 1 버전도 계속해서 개선되고 있고, 특히 1.4 버전에서는 1.3 대비 엄청난 성능 향상이 있었습니다. SW 아키텍트인 Zackary Chapple은 GitHub에서 Angular 성능 모니터링 컨트리뷰터로 활동하고 있으며, 1.2 부터 1.5까지 페이지 로딩 성능을 비교한 적이 있습니다. 1.4에서 놀라운 성능 향상이 있었네요.

 

벤치마크 결과를 보면 Angular 1라고 적힌 경우가 많은데, 1.4 이전과 이후에 성능이 크게 차이나니 사용한 버전을 확인해야 제대로 된 비교가 가능합니다. Angular 2가 빠르면 좋겠지만... 그것을 위해서 1.4 이전 버전으로 비교하는 것은 과장된 결과를 낼 것으로 생각됩니다. 실제로 1.3과 비교한 결과를 보면 Angular 2와 큰 차이가 나는 것을 확인할 수 있습니다. 일단.. Angular 2가 빠르긴 하죠... Baseline은 순수한 JavaScript로 최적화된 코드입니다.

 Deep Tree를 사용하여 성능을 비교한 결과는 아래 그림과 같습니다. 주의할 점은 Angular 1의 버전이 1.3이라는 것입니다.

 Virtual Scrolling Table에서 성능을 비교한 결과는 아래와 같습니다. 이전에 언급한 것과 같이, Angular 1의 버전이 표기되지 않은 경우는 제대로 된 결과라고 볼 수 없습니다.


다행히 정확하게 버전이 표기된 버전으로 테스트를 수행하는 프로젝트가 있습니다.

Angular 이외에도 많은 JavaScript 프레임워크에 대해 벤치마크를 수행하고 있습니다. 테이블의 행을 생성하거나 값을 바꾸고, 행을 추가하고 비우는 동작을 수행하는데, 이 결과에서 필요한 부분만 요약하면 아래 그림과 같습니다.

 Angular 1 도 최신 버전인 1.5.8을 사용하고 Angular 버전은 2.0 final 버전으로 발표되었던 2.0.0-rc.5를 사용하고 있으며, React도 비교하고 있습니다. Angular 2는 다행스럽게도(?) Angular 1보다 나아진 성능을 보여주고 있으며 React와 비슷한 것으로 보이네요. 여기에서 Angular 팬으로서 React와 비교하자면.... React는 View에 국한된 기능을 제공하는 라이브러리이고 Angular 2는 SPA를 위한 프레임워크이면서도, 뷰 처리에 React와 비슷한 성능을 보여주는 것은 아주 뿌듯한 모습이네요 ㅎㅎㅎ 더이상 React에게 성능으로 비교당하는 일이 없었으면 좋겠습니다...

 위 차트에서는 VanillaJS가 가장 빠른 성능을 보여주지만, 프레임워크는 기능과 성능을 함께 검토해야 합니다. 성능이 빠른 것을 무조건 쓰려고 하면 순수한 JavaScript를 사용하는 것이 낫겠죠. 물론 생산성은 보장 못하겠지만...


 속도의 측면에서는 주목할 만 한 결과물이 계속 나오고 있는 것으로 보입니다. Angular 2를 사용하지 않는 이유로 '속도'가 꼽히는 일은 당분간 없겠네요.


장점 ② : 체계적인 개발 방법

 그럼 이렇게 장애물도 많고 속도도 빠른지 딱히 모르겠는데 왜 Angular 2를 써야 하는 건가... 그 해답은 프레임워크를 사용하는 본질인 생산성 향상에 있습니다. 프레임워크를 도입하는 수고로움에 비해 생산성이 나아지지 않는다면 프레임워크를 사용하는 의미가 없겠죠.


 Angular 2에서 지향하는 바는 이렇습니다.

  • Mobile Oriented
  • Modern browsers only
  • Dynamic loading, Server-side rendering
  • RxJS 지원, Reactive Programming
  • Testing
  • Angular Material 2
  • WebWorks
 일단 모바일과 최신 브라우저를 우선으로 지원하는 것을 볼 수 있습니다. 언제부터인가 PC보다 모바일 디바이스를 이용하여 인터넷에 접속하는 비율이 높아졌고, 웹 앱 개발 추세도 간결하고 빠른 성능에 집중하고 있는 것 같습니다. 반응형 웹 디자인에 대응하기 위해 Angular Material 도 2 버전으로 지원하려고 하는 것 같네요.
 여기에 다이나믹 로딩과 서버사이드 렌더링을 지원하는 것도 성능 향상을 위한 방안입니다.
 Angular 1에서부터 테스팅의 편의를 위해 ng-mock 과 같은 객체를 지원하기도 했었는데 이것도 2에 그대로 반영되었습니다.
 컴포넌트 기반의 개발방식과 웹 워커를 도입한 것은 웹 표준에도 잘 맞고 있네요.
 RxJS를 지원하면서 Reactive Programming을 도입한 것도 최근 개발 추세를 잘 맞추고 있는 것으로 보입니다.


 Angular 2를 사용하면 최신 트렌드의 혁신적인 개발 트렌드를 직접 따라갈 수 있습니다. 물론 공부할 양이 더 늘어나겠지만.... ㅎ


 Angular 2에서는 디버깅을 위해 Augury라는 툴도 발표했습니다. 크롬 확장 프로그램으로 설치하여 Angular 2 어플리케이션의 내부 상태를 확인하는 데에 도움이 되는 툴입니다.


 Augury를 이용하면 컴포넌트들의 관계와 내부 정보, 의존성의 계층을 확인하거나 라우팅 구조를 따라가 볼 수 있습니다. 값을 찍어보는 디버거로서의 기능 이외에 개발에 도움을 주는 많은 기능을 담고 있네요.

  • Component Relationships
  • Detailed Component Info
  • Dependency Hierarchy
  • Change Detection Strategy
  • Editable Component Properties
  • Router Structure


크롬에서 이런 계층을 볼 수 있다는 것이 신기하네요 ㅎㅎㅎ 값이 변경되면 그 값을 바로 확인할 수 있고 원하는 값으로 변경도 가능합니다.



결론 : Angular 2 써야 할까? 언제?


 결국 Angular 2를 써야할지 판단하는 것은 생산성 향상에 도움이 되는지를 생각해야 합니다. 도입하는 수고로움과 향상되는 생산성, 유지보수에 대한 공수를 잘 비교해보고 더 나아지는 점이 있을 때 도입을 하면 되겠죠.


 Angular 2를 사용하면 CLI와 Augury와 같은 툴을 통해 좀 더 체계적인 개발이 가능하고, 서버사이드 렌더링과 RxJS를 사용한 Reactive Progrmaming, Web Component와 Web Worker와 같은 최신 기술을 자연스럽게 사용할 수 있습니다. Angular 2에 모두 포함되어 있으니 추가로 다른 라이브러리를 가져다 사용할 필요가 없죠.

 최종적으로 Angular 1이 그랬던 것처럼 개발 생산성 향상에 큰 도움이 될 것 같습니다.


 다만, 아직 변동사항이 많고 사용자들의 경험이 많지 않아 지금 단계에서 도입하는 것은 많은 어려움이 예상됩니다. 공식 사이트에 가이드 문서가 잘 되어 있지만 가이드가 모든 것을 해결해 줄 순 없고... 어려움이 생겼을 때 찾아볼 소스가 아직은 적네요.



 개인적인 결론은, 아직 프로젝트에 도입할 정도로 성숙하진 않은 것 같습니다. 하지만 더 나은 방향으로 계속 진행되고 있는 것을 곳곳에서 볼 수 있네요. 조금씩 공부하면서 진행상황을 계속 지켜볼 예정입니다.


감사합니다.


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함