2018 한 해를 돌아보며…

2018년.

기나고도 짧은 1년이 지나가고, 이제 2019년이 다가옵니다.

그런 기념으로, 2018년의 중요하고 변화점이나 느낀 점을 살펴보고 2019년에 달성하고 싶은 목표를 적어보려 합니다. (물론 개발적으로요.)

1월 – PyxisBaseApp (MVVM + Dagger)

2018년 1월 20일, PyxisBaseApp라는 MVVM + Dagger + Databinding + Retrofit 스택을 가진 베이스 앱을 작성하기 시작, 2018년 12월 31일 기준으로 배포 버전 1.3.3, 커밋 수 316개의 적당한 규모의 베이스 앱을 제작하였습니다.

이 베이스앱의 전/후로 지금까지의 본인 안에서의 개발 패러다임이 바뀌었는데, 전에는 일정한 패턴 없이 Activity 하나에 집중하는 형태였다면 지금은 일정한 패턴을 따라서 MVVM 과 Continous Integration을 목적으로 개발하고 있습니다.

이 때 MVP를 거치지 않고 MVVM으로 바로 거친 이유로는 당시 같은 회사에 계셨던 개발자분이 MVP를 사용하셨는데 이 구조를 보니까 Activity – Contract – Presenter가 강제되는 형태로 조금 비효율적으로 보였기 때문입니다 . 그리고 마침, 안드로이드에서 Android Architecture Component 라고 하는 구조가 나왔었기에 MVVM을 좀 더 쉽게 작성할 수 있었습니다.

이렇게 PyxisBaseApp는 계속해서 변화를 거쳐 9월 29일에는 JFrog Artifactory를 통해 본격적인 라이브러리 형태의 베이스 앱을 제작했고, 나름대로 만족할 구조가 탄생하였습니다.

3월 – Annotation Processor

1월과 2월에는 MVVM 구조를 중점으로 적용했다면, 3월에는 중복되는 코드를 줄이기 위한 Annotation Processor에 대해 집중했습니다.

지금까지 어노테이션을 Reflection 을 통한 접근방법만 사용했었는데, 타겟으로 하는 어노테이션이 있는 클래스나 메서드 대상으로 코드를 생성하는 Annotation Processor의 도입으로 Dagger의 Activity, Fragment, ViewModel의 주입이 어노테이션 하나를 부착하는 것 만으로도 끝나고, CustomView의 Attribute 파싱 등을 빠르게 할 수 있었습니다.

물론, 이 떄 공부한 지식으로 Annotation Processor 기반 기술을 도입하거나 분석할 때 큰 도움이 되었기도 했습니다. (Databinding나 Dagger 등)

7월 – RxJava

계속 미루고 왔었던 RxJava 도입을 이 때부터 시작하였습니다. 처음에는 Listener 형태의 Callback를 Observable로 변경하는 것에서부터 Socket 통신의 RxJava wrapper까지 작성하면서 이전에는 쉽게 달성하지 못했던 스레드 관리나 데이터 소스로부터의 효율적인 합성을 달성하였습니다.

그리고 이 때, SocialLogin 기능과 RxJava를 합친 RxSocialLogin(https://github.com/WindSekirun/RxSocialLogin)을 개발하고 배포하였습니다.

8월

산업기능요원으로 근무하다보면 언젠가 찾아오는 시련인 훈련소(._. )를 다녀왔습니다. 따라서 이 때는 기록이 없습니다.

9월 – Docker를 통한 SaaS 컨테이너 배포

이 때까지 PyxisBaseApp는 프로젝트마다 멀티모듈로 포함되어 있었기에 버전 관리가 안되고, 여러 프로젝트마다 다른 베이스 앱 코드를 가지고 있었기에 코드 관리도 더더욱 힘들었습니다.

그래서 Docker를 공부하고 새 인스턴스에 JFrog Artifactory를 올리고 PyxisBaseApp를 모듈 단위 배포가 아닌 라이브러리 형태 배포로 변경하였습니다.

추가적으로, 처음으로 BLE 앱을 원개발하면서 RxAndroidBle(https://github.com/Polidea/RxAndroidBle) 도 사용해보았습니다. 다소 어려웠지만 notify, write 이벤트를 쉽게 처리할 수 있었던 것이 가장 마음에 들었습니다.

12월 – Jenkins 도입

이전에는 CircleCI를 사용했었으나 Private project에는 적용하지 못하고 오픈 소스 프로젝트만 사용하였습니다. 그래서, 꽤나 이전부터 계획은 있었음에도 쉽게 도입할 수 없었던 Jenkins를 Docker의 힘을 빌려 사용하게 되었습니다.

그리고 12월 25일, 대망의 확장 공사를 시작하면서 지금까지 분리되어있던 블로그 인스턴스 + (Artifactory/Jenkins) 인스턴스를 합쳐 지금의 인스턴스로 이사하면서 메일 서버나 FTP 서버 등도 전부 Docker를 통해 관리하게 되었습니다.

마무리

2018년에만 공부하고, 새로 도입해서 실제 사용한 기술이 MVVM, DataBinding, RxJava, Dagger (DI), Retrofit, ObjectBox, Docker, Jenkins, AndroidX, Static Analysis 로 작은 것 까지 포함하면 20개는 족히 넘을 것 같습니다.

2019년에는 빠르게 변화하기 보다는 기존에 사용하던 기술을 좀 더 가다듬어 좀 더 전문적인 지식을 가질 수 있도록 열심히 갈고 닦아야 될 것 같습니다.

그리고, 대망의 그 날(2019-04-19)도 얼마 남지 않았고요. 후후…

새 인스턴스로 확장 이전과 후기

이번 연휴(2018. 12. 22 ~ 2018. 12. 25) 동안 지금까지 운영해오던 UzukiLive 서버를 확장이전 하여 새롭게 환경을 구축하게 되었습니다.

기존 인스턴스와 문제점

기존 환경은 이렇게 설정되어 있습니다.

  • Vultr VC2 1core 2GB (UzukiLive 인스턴스) -> 블로그, nextcloud. 도커로 되있지 않음
  • Vultr VC2 2core 4GB (Artifactory 인스턴스) -> Artifactory, Jenkins. 도커로 되어있음

그리고 메일 서버의 경우 Zoho 플랫폼을 빌려 사용하였고, 처음에 삽질을 너무 크게 한 나머지 uzuki.live 로 접속하면 SSL 에러가 발생하곤 했습니다.
그 외 문제점이라고 하면 FTP를 쉽게 사용할 수 없거나, 너무 설정이 여기저기 있어 확장하려고 해도 쉽지 않았습니다. (오죽하면 인스턴스를 두개 생성해서 관리를 했지만요… (._. )

당연히 비용도 비용이니 좋지 않은 사양에 월 30달러나 지불해야 한다는 것은 이해가 가지도 않긴 합니다.

따라서 이번 연휴때 계획을 잡고 신규 인스턴스에 전부 이전하기로 결정했습니다.

신규 인스턴스

신규 인스턴스는 Vultr의 VC2 4core 8GB, 100GB SSD 입니다. 이전 사양보다 약 2(Artifactory 인스턴스 기준) ~ 4(UzukiLive 인스턴스 기준)배 이상 사양이 증가하였습니다.

사양을 대폭 올린 이유로는 Jenkins 때문인데, 2core 4GB 사양에서 gradle 빌드를 두 개 이상 돌리는 순간 컨테이너가 메모리 부족으로 죽어버리는 대참사가 발생하여, 빌드를 두 개 이상 동시에 돌리더라도 문제가 없도록 구성하였습니다.

신규 인스턴스는 모든 요소가 Docker에 의해 관리되는 Dockerize 환경을 사용할 것이고, 아래 범주로 서비스를 관리할 예정입니다.

  • Reverse Proxy -> nginx
  • Stack: Infra -> adminer, pure-ftpd, docker-telegram-notifier
  • Stack: Blog -> MariaDB + WordPress
  • Stack: Build-Automation -> Jenkins, Artifactory
  • Stack: Mail -> docker-mailserver(IMAP/SMTP) + rainloop (Web UI)
  • Stack: Intro -> uzukilive-intropage
  • Stack: Octobox -> Octobox + Redis + PostgreSQL

그러면, 각 범주마다 설명을 약간 추가하면서 기능을 소개하려 합니다.

Reverse Proxy + SSL

기존 UzukiLive 에서도 사용했던 Nginx를 사용하고, 여기에 LetsEncrypt를 이용하여 모든 외부용 서비스에 SSL를 제공할 계획입니다.

보통 nginx-proxy + letsencrypt-companion 조합으로 사용하지만 이 조합의 경우 docker 소켓에 붙어 일정 시간마다 스캔을 해서 추가하는 방식으로 되어있어, 그거보다는 좀 더 귀찮지만 하나의 설정 파일(conf)로 존재하는 것이 좋다고 생각되었습니다.

따라서 새 서비스를 연동할 때 마다 아래의 명령어를 통해 인증서를 발급받았습니다.

docker run -it --rm -v /data/cert:/etc/letsencrypt -v /data/cert-data:/data/letsencrypt certbot/certbot certonly --webroot --webroot-path=/data/letsencrypt -d uzuki.live

저 방법을 사용하기 위해서는 일정의 예제 conf 파일을 만들어 nginx를 가동시킬 필요가 있는데, 샘플 nginx 파일을 만들고 DONAME_NAME 만 교체해서 생성하도록 했습니다.

server {
    listen      80;
    listen [::]:80;
    server_name uzuki.live;

    location / {
        rewrite ^ https://$host$request_uri? permanent;
    }

    location ^~ /.well-known {
        allow all;
        root  /data/letsencrypt/;
    }
}

Stack: Infra

여기에는 3개의 서비스가 들어가는데, adminer 는 MySQL/MariaDB의 정보를 보거나 수정할 수 있는 프로그램으로 phpmyadmin 대체용입니다

그 다음으로 pure-ftpd는 FTP 서버로 /home/pyxis 경로에 접근하여 데이터를 주고 받을 수 있게 설정했습니다.

마지막으로 docker-telegram-notifier 는 미리 만들어둔 Telegram bot로 컨테이너의 시작/중지 등의 상태를 보내줍니다.

가령 Jenkins가 시작되었다면 아래의 메세지를 보내줍니다.

Started container jenkins
Image: windsekirun/jenkins-android-docker:1.0.2
Container ID: ae8f526e8b42d216146fb68ee49f6506631259780f3c75195718786da6245cb6
오늘도 약 400개의 메세지를 받아내는 우즈키(..)

Stack: Blog

여기에는 2개의 서비스가 들어가는데, 워드프레스와 그 DB로 MariaDB를 선택했습니다. 기존 인스턴스에는 MySQL로 되어있고, 이 데이터를 그대로 가져갈 필요가 있었습니다.
따라서 PostgreSQL 보다는 MariaDB를 선택했습니다.

주소는 기존의 blog.uzuki.live 에서 pyxispub.uzuki.live 로 변경했는데, 기존 주소로 들어가면 새로운 주소로 리다이렉션 되도록 기존 인스턴스의 nginx 단을 수정했습니다.

기존 인스턴스는 2주 뒤인 1월 11일쯤에 제거될 예정입니다.

Stack: Build-Automation

여기에는 2개의 서비스가 들어가는데, 각각 Gradle Repository용 Artifactory와 Jenkins가 들어갑니다. 이 두개 서비스에 대해서는 일전 블로그 글로 설명한 적이 있으므로 별도로 설명할 것은 없다고 생각됩니다.

다만 아주 잉여롭지만 봇을 만든 겸에 빌드 시작 / 결과를 알려주는 별도의 Jenkins 호환용 그루비 스크립트를 작성해서 적용했습니다

Stack: Mail

기존 메일(pyxis@uzuki.live) 는 Zoho Mail에서 수신/발신하도록 되어있어 내 것이 아니기도 한 존재였습니다.
따라서 이번 인스턴스에는 IMAP/SMTP 서버를 직접 구축하여 메일을 수신/발신할 수 있도록 설정하였습니다.

…다만, vultr가 SMTP 포트인 25번을 막아버리는 바람에 일단은 Gmail에 의존하여 발신하도록 설정하였으나 좀 더 Postfix를 공부하여 수정할 계획입니다.

메인 화면
글쓰기 화면

웹 메일 UI는 rainloop를 사용하였고, 특출나게 UI가 세련된 건 아니지만 나름대로 들어갈 기능은 전부 포함되어 있습니다.

Stack: Intro

물론 반응형입니다.

CSS Toolkit인 타키온(https://tachyons.io/) 을 이용하여 5~10분만에 대충 만든 인트로 페이지로, 이 서버에서 제공하는 서비스의 링크와 Github, Telegram, Contact 링크를 포함합니다.

물론, 이 인트로 페이지(라고 해도 HTML 1개 + CSS 1개) 도 docker 이미지를 만들어서 제공했으며, 도커 이미지는 https://github.com/WindSekirun/uzukilive-intropage 입니다.

Stack: Octobox

Octobox 라고 하는 Github의 알림을 관리하는 서비스가 있는데, 이 서비스가 self hosted로 하면 프라이빗 프로젝트까지 포함되어 설치하게 되었습니다.

이 서비스의 자세한 설명은 공식 홈페이지 (https://octobox.io/) 를 들어가는 것이 편리합니다.

마무리

일전에도 Jenkins나 Artifactory를 도커로 활용하고 있었지만 이번 기회를 통해 도커를 통한 관리가 얼마나 확장성과 자유성을 가져주는지 깨달았습니다.

개인 목적으로는 나름대로 규모가 있고, 따로 설치하라고 한다면 아마 멘탈 여러번 나가서 쉽게 던졌을텐데, 명령어 한 두줄 만으로 모든 것을 설정할 수 있다는 것이 큰 장점인 것 같습니다.

컨테이너가 14개가 되다보니 docker-compose로 각 스택별로 모아 필요한 스택만 켜고 끄고 할 수 있게 설정해두니, 패치할 때도 다운타임이 5~10분 내로 할 수 있다는 것도 좋았습니다.

열심히 가동되는 컨테이너(들)

그러면, 새로운 인스턴스와 새로운 환경에서 남은 6일, 앞으로 다가올 2019년에도 PyxisPub와 이 주인장(._. … )을 잘 부탁드립니다.

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가 직접 와서 강의하니 좀 더 집중해서 들을 수 있을 것 같습니다.

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