GDG Devfest Seoul 2018 참가 후기

Shot on Galaxy S8 @세종대학교 광개토관 입구

2018. 11. 10. 토요일에 세종대학교 광개토관에서 개최된 GDG Devfest Seoul 2018 에 일반 참가자로 참여했습니다.

개발 관련 컨퍼런스 참여는 이번이 두 번째로, 첫 번째는 소규모로 진행된 모임 식의 컨퍼런스였고, 두 번째가 금일 참가한 Devfest 입니다.

Shot on Galaxy S8

이 중, ‘Data Uni-Directional Architecture in Android’, ‘함수형 프로그래밍과 안드로이드 테스팅’, ‘빠르다는 것 그 이상, Isomorphic PWA’, ‘Android DataBinding for Modularization, ViewModel and Testing’ 총 4개 세션에 대해 참가하였으며, 마지막 세션은 개인 사정으로 인하여 불참하였습니다.

각 세션에 대해 총평을 하기 전 부스에 대해 간단히 설명해보자면, 참여한 부스는 GDG Developer, 카카오페이, 레이니스트, 알지피코리아, 크래커나인 5개 부스로 (나머지 1개 부스도 있었지만 갈 당시에는 부스 준비중이라 참여를 못했습니다.) 이 중 그나마 관심이 갔던 것이 크래커나인 이었습니다.

다만 막상 설명을 들었을 때 제플린과는 호환이 안된다는 것을 알게 되어 조금 아쉬웠던 점도 있습니다. (직원분 말씀으로는 Sketch에서 export 하신다고 하였지만, 현재 회사에서 디자인 부서는 제플린을 사용하고 있기 때문입니다.) 다만 다음에 Sketch를 사용할 일이 있다면 꼭 사용해보고 싶은 기능일 만큼 충분히 매력적이긴 합니다.

이제 들었던 4개의 세션에 대해 간단히 말하려고 합니다.

Data Uni-Directional Architecture in Android

Uni-Directional Architecture (단뱡항 아키텍쳐) 를 대상으로 강의를 진행하셨고, Flux, Redux, MVI에 대해 각각이 가지는 속성과 차이점에 대해 코드와 같이 진행되었습니다.

이전 MVI에 대해 접해본 적은 매주 발송되는 Android Weekly나 Medium에서 발행되는 포스트밖에 없어 실제로 어떤 개념인지에 대해 명확히 알지는 못했는데, 나름대로 강의를 듣고 정리하였습니다.

먼저, View 와 State 간의 분리를 진행하고 State가 한 방향에서만 수정을 할 수 있다는 것이 UDA의 중점 개념이었던 것 같습니다. State 와 View가 각각 영향을 줄 경우에는 모든 작업이 비동기적으로 이루어지기 때문에 언제 어느 액션이 발생했는지 모르고, 이에 따라 사용자에겐 버그로 보일 수 있기 때문입니다.

따라서 하나의 작업이 끝나면 다음 작업을 진행하는 ‘동기적 작업’ 을 이용해 작업이 순차적으로 진행될 수 있게 하고, 그 과정에서 State의 관리에 이점을 가지거나 State의 변경 지점이 명확해지기 때문에 코드에 대한 안정성이 높아진다는 것 같았습니다.

Capture on https://speakerdeck.com/maryang/data-uni-directional-architecture-uda-in-android?slide=72

즉 위의 사진이 중점 포인트라고 할 수 있습니다.

하지만 현재 사용하는 패턴이 DataBinding와 RxJava를 이용한 MVVM 패턴이고, 데이터 바인딩의 양방향 데이터바인딩은 UDA에서 제시하는 단방향 접근으로 되지 않기 때문에 적용하기 힘든 부분이 있다고 판단했습니다. 이에 관련되어 질문을 드리려 했으나, 앞에 있던 사람이 먼저 질문하여 같이 답변받았으나 데이터바인딩과는 호환이 좀 어렵다고 답변을 받았습니다.

다만 복잡한 State의 관리가 필요한 곳에 부분적으로 도입하면 괜찮을 것 같다는 생각이 있었습니다.

함수형 프로그래밍과 안드로이드 테스팅

안드로이드의 테스트인 Local과 Instrument 테스트 중에서 Local 테스트, 즉 단위 테스트에 관련된 강의였습니다.

이 강의에서는 테스트 가능한 코드를 잘 작성하기 위한 전략에 대한 강의를 진행하셨는데, 중점이 된 사항이 있습니다.

테스트 가능한 코드와 불가능한 코드 분리

단위 테스트에 사용되는 android.jar 는 실제 코드를 포함하고 있지 않은 파일이기 때문에 Android Platform API에 의존하는 코드는 테스트가 불가능합니다. 반면에 Android Platform API에 의존하지 않는 순수 비지니스 로직은 테스트가 가능합니다.

MVP 패턴에서는 Presenter를, MVVM 패턴에서는 ViewModel를 테스트 가능하게 하려면 Android의 어떤 Platform API에 의존하지 않게 하여 Mock이 필요 없이 검증만 하면 되는 방식으로 진행해야 된다고 했던 것 같습니다.

View는 최대한 Passive하게 작성

이 말은, View는 어떤 비지니스 로직을 가지지 않고 Passive 하게 (a.k.a 멍청하게) 작성하는 것을 으미합니다.

위 두 사항을 제대로 반영하려면, 함수형 프로그래밍에 나오는 순수 함수(Pure Function. 다른 말로는 1급 함수라고도 합니다.) 를 적용하면 되는데, 순수 함수는 외부의 다른 State에 대해 영향을 받지 않고 주어진 Input에 대해 항시 같은 Output를 반환하는 함수입니다. 이렇기 때문에 순수함수는 그 특성 덕분에 Side effect가 없으며, 프로젝트의 종속적이지도 않게 되기 때문에 재사용성이 가능합니다.

이 순수함수를 이용하여 작성하게 되면, 작성한 비지니스 로직의 테스트는 해당 메서드의 반환이 예상한 대로 도출되었는지 확인하면 됩니다.

전체적으로 이미 알고 있던 내용이었지만, 지금 본인이 구성하고 있는 ViewModel 이 Android Platform API에 반쯤은 의존하고 있었다는 사실이 조금 아쉽게 느껴졌습니다. 그래서 본 강의를 들으면서 비지니스 로직을 최대한 분리하는 방향으로 설계를 해야 되는가 싶기도 했습니다.

빠르다는 것 그 이상, Isomorphic PWA

왜 갑자기 다음 Mobile 세션인 Flutter를 듣지 않고 이 강의를 듣게 된 것은, 2주 전 쯤에 전 회사 동료와 현 회사 동료 3명이서 같이 저녁을 먹은 적이 있었는데, 그때 나온 이야기가 PWA에 대한 이야기였기 때문입니다.

그 개발자가 ‘싱글 페이지에 라우터를 부착하여 렌더링을 진행하고, 서비스 워커로 네이티브 기능을 활용할 수 있다’ 라는 말을 했었는데, 그 말을 듣고 어느정도 찾아보았으나 프론트엔드 개발을 진행한 경험이 거의 없기 때문에(아주 예전에 AngluarJS + Cordova로 하이브리드 앱 프로젝트를 진행한 적이 있었긴 했다.) 애매하만 이해하고 있었습니다.

그래서 이 세션이 있다는 것을 보고, 지금은 정확히 알지 못해도 차후에 서비스를 설계할 때 큰 도움이 될 수 있지 않을까 하는 생각에 들었습니다.

해당 강의에서는 ‘느린 웹은 사용자에게 공포 영화보다 더 큰 공포를 준다‘ 라는 말로 시작하면서 서비스의 웹 앱에 대해 Dynamic Code Splitting, Lazy Loading, Server-Side Rendering, SPA 등을 활용하여 사용자가 웹을 로드하고 인풋을 받을 때까지의 시간(First Interactive Time)을 최소화하는 기나긴 과정을 설명했습니다.

먼저 SPA(Single Page App) 에 다루었는데, 기존의 HTML 파일 단위로 링크를 이동하는 것이 아닌 하나의 앱 안에서 라우터(Router)로 경로를 불러오는 기술을 말합니다. 이로서 얻는 이점은 파일 단위로 링크를 이동하는 것이 아니기 때문에 캐시 처리에 용이하고, 로드가 끝난 다음에는 마치 네이티브와 같은 네비게이션을 보여주기 때문입니다.

다만 이 SPA에도 단점이 있다면, 처음 로드하는 시간이 매우 길다는 것입니다. 그에 대한 근본적인 문제는 Javascript, 즉 JS 파일이 로드되기 위해서는 Parse / Compile / Execute 과정을 거쳐야 하는데 이 과정이 브라우저의 메인 스레드를 블로킹하여 진행되기 때문에 사용자는 작업이 끝날 때 까지 기다려야 합니다.

The Cost of Javascript, https://medium.com/dev-channel/the-cost-of-javascript-84009f51e99e

위 사진은 같은 용량(170KB) 인 JS 파일과 JPEG 파일을 로드했을 때 로드하는 데에 걸리는 시간을 측정한 것입니다. 여기서 JPEG는 0.1초 안에 모든 작업이 완료되었음을 알 수 있지만, JS의 경우 최대 3초까지 작업이 걸린다는 것을 알 수 있습니다.


The Cost of Javascript, https://medium.com/dev-channel/the-cost-of-javascript-84009f51e99e

이렇기 때문에 JS 파일의 사이즈를 줄여 로드하는 시간을 최소화하는 방법이 있는데, 그것이 구글에서 발표한 PRPL (Push Render Pre-cache Lazy-Load) Pattern이다. PRPL 패턴은 MVVM와 같이 디자인 패턴의 한 종류가 아닌 웹을 배포할 때의 예시 패턴이라고 볼 수 있습니다.

PRPL의 주요 관점은 주요 리소스를 먼저 로드하고, Route를 진행합니다. 이 과정에서 불러올 확률이 낮은 것들은 해당 Route가 불렸을 때 Lazy Load 하는 것입니다.


The Cost of Javascript, https://medium.com/dev-channel/the-cost-of-javascript-84009f51e99e

이와 관련해서 Dynamic Code Splitting 과 Lazy Load가 사용되는데, 이는 상기되었던 사항과 같이 JavaScript 로드는 메인 스레드를 블로킹하여 진행되기 때문에 Router 기반으로 페이지를 잘게 나눠 처음에 클라이언트에 렌더링 목적으로 전송되는 JS 파일을 최소화하는 것입니다.

중요 컴포넌트(랜딩, 또는 방문 페이지를 분석했을 때 사용자가 처음에 방문할 확률이 높은 페이지)는 초기 로드때 가져오며, 나머지는 비동기나 Lazy Load를 처리합니다. 해당 강연자는 React를 사용하고 있었기에 React-Loadable 라는 라이브러리를 사용했다고 합니다.

그 다음, Minify 와 Compress가 있는데, 컴포넌트 별로 분리한 JS를 한번 더 압축시키는 것입니다. Minify 에는 Webpack를, Compress에는 일반적으로 사용되는 gzip를 사용했다고 합니다.

상기 문단에 잠깐 설명되었던 중요 컴포넌트에 대해서, 방문자 수의 95%를 차지하는 것이 랜딩 페이지 및 이벤트 정보 페이지이기 때문에 사용자가 인풋을 하기 보다는 정보를 표시하는 페이지로 분류된다고 설명하면서, 사용자가 필요한 정보를 빠르게 노출하여 First Time를 줄이는 것이 좀 더 효과적이라고 했는데 그 사항을 달성하기 위해 도입한 것이 Server-Side Rendering라고 합니다.

Server-Side Rendering의 경우 서버와 클라이언트 둘 다 렌더링을 하여 클라이언트단에서 렌더링 하는 시간을 최적화 하는 것이라고 표현할 수 있습니다.

Draw by draw.io, 필기로 그린 것으로 원래 자료와는 다소 차이점을 보일 수 있습니다.

간단히 도식화하면 위와 같은데, 클라이언트단에서 최상단 / 를 요청하면 서버가 렌더링한 Static file를 내려주고, 클라이언트에서는 assets를 다운로드 받으며 렌더링을 진행합니다. 서버가 렌더링한 SSR HTML 과 클라이언트가 렌더링한 CSR HTML 이 같으면 이상적(Isomorphic) 로 표현한다는 것이라고 설명하셨습니다.

이 과정에서 서버가 렌더링 할 때 API 요청이 필요한데, 서버가 렌더링 할 때에는 클라이언트가 렌더링할 때와는 다르게 DOM 객체가 존재하지 않고, React에서의 Lifecycle가 호출되지 않기 때문에(정확히는 라이프사이클에서 비동기적 처리가 되지 않는다고 하셨는데, 정확히 들은건지는 모르겠다.) 분기 처리를 다 해야 된다고 말했던 것 같습니다.

마지막으로 짧은 시간을 남기고 PWA에 대해 설명했는데, PWA 체크리스트 상의 항목을 만족하면 된다고는 했었는데 너무 빨라서 정확히 듣지 못했으므로 차후에 포스팅으로 정리할 수 있으면 정리하려 합니다.

Android DataBinding for Modularization, ViewModel and Testing

이 강의에서는 Databinding 의 기본 사용법 (표현식, 어노테이션, 양방향 데이터바인딩)에 대해 설명하고, 데이터바인딩이 내부에서 어떻게 작동하고 작동되는 코드에 영향을 주는 dirtyFlags가 어떻게 매핑되어 구성되어 있는지에 대해 설명했습니다.

다만 이 강의에 대해서는 별로 집중하지 못했는데, 아마 Android Dev Summit 2018의 이 세션과 60% 이상 동일하다고 할 수 있습니다.

다만 마지막의 dirtyFlags 에 대해서는 지금까지 데이터바인딩을 사용하면서도 내부 코드를 분석해도 표현식이 어떻게 바인딩 어댑터에 사용되는지를 확인했을 뿐이지, 그 곳에 존재하는 dirtyFlag에 대해서는 신경을 쓰지 않았기 때문에 새로운 내용이었습니다.

이에 관련해서는 차후에 따로 정리하겠습니다.

마무리

전체적으로 4개 세션에 대해 평가하자면 대체적으로 만족했습니다. 가장 아쉽게 느낀 것은, 평소에 잘 알고 있는 사항이 아니라 애매하게 알고 있던 사항이나 모르는 사항에 대해 들었으면 좀 더 유익한 시간이 되지 않을까 싶었습니다.

다시 시간을 돌린다면, ‘GCP를 활용하여 코딩 없이 앱 서비스 분석 인프라 구축한 삽질기’ 와 ‘실전 SPA 상태관리 톺아보기’, ‘GTA5를 이용한 자율주행 자동차 만들기’ 를 듣고 싶다고 막연하게 생각했었습니다.

아마 다음 참여할 컨퍼런스는 11월 22일(목요일) 에 열리는 JetBrains Day 서울 2018로, 처음 코틀린을 접할 때 큰 도움이 된 강사분인 Hadi Hariri가 직접 와서 강의하니 좀 더 집중해서 들을 수 있을 것 같습니다.

마침 장소도 오늘과 같은 곳이니, 이번엔 덜 헤멜 수 있도록 바라면서 글을 마칩니다. 🙂