안녕하세요.

프론트엔드 개발자를 꿈꾸는 23살 현역 군인입니다.


저에게 벨로그는 그냥 눈팅만 하면서 정보를 얻어가던 곳이었는데,

프로젝트가 완성된 김에 썰좀 풀어보고자

이 글을 작성하게 되었습니다.


제가 이 프로젝트에서 생각했던 모든 것, 겪었던 것들

전부 이 글에 써보려고 합니다.


그래서 글이 좀 많이 깁니다.

양해부탁드리면서 글을 시작해볼게요.


개발 개요

  • 개발 기간: 대략 3개월
  • 스택: Next.js / Typescript / Firebase
  • 군대라서 code-server 열어서 개발했습니다.

만들게된 계기

저는 종종 장난감처럼 인터랙션할 수 있는 토이 프로젝트를 하는 것을 즐깁니다.

아무래도 제가 존경하는 메이커 김종민님의 영향을 많이 받았던 것 같은데요.

그런 행동들 덕에 이번 타임 타이머 프로젝트도 진행할 수 있게 되었습니다.


프로젝트의 시작은 시중에 판매되고 있는 타임 타이머 제품을 보고 나서 였습니다.

해당 제품은 단순한 1시간 타이머였는데, 다른 제품들과 구별되는 차이점이라면,

시각성이 매우매우 훌륭하다는 점입니다.


타임 타이머는 손으로 중앙에 돌출되어 있는 모터를 돌려 시간을 맞추게 되는데,

군대 동기가 이 제품을 구매하여 직접 손으로 시간을 맞추는 것을 보며

인터랙션 쪽에서 영감을 받게 되었고, 이걸 한 번 웹으로 옮겨보자는 생각을 하게 되었습니다.


프로토타입 제작

저는 빠르게 바닐라 JS를 이용하여 손으로 시간을 맞출 수 있는 시계를 제작해 보았습니다.

( 아쉽게도 이 시절에 작동하던 영상이 없네요... )

Pointer Event 를 이용하여 사용자의 포인터 좌표를 구하고,

간단한 수학과 선형대수를 이용해 시계가 돌아가는 프로토타입을 구현했습니다.


결과는 굉장히 만족스러웠고,

그렇게 저의 일용할 양식이 되는 간단한 프로젝트가 되나 했으나…


직접 타임 타이머를 만들기로 결심하게 되다

앞서 소개한 타임 타이머를 사용하던 동기가 저에게 와서

” 오 이거 뭐임? 웹으로 만드는 거임? 그럼 나도 쓸 수 있음? ”

라고 하길래 저는,

" ㄴㄴ 만들 계획 없음. 그냥 장난감으로 돌아가는 거만 만든거임 “

라고 말했습니다.

그런데 말하고보니 지금까지 제가 무언가 배포까지, 끝까지 진행해본게 그닥 없더라고요.

그래서 오히려 좋은 기회다.
프로토타입도 괜찮겠다.
이거로 끝장을 보자.

이런 생각을 가지고 프로젝트를 끝까지 진행해서 배포해보자고 마음을 잡게 되었습니다.

게다가 저는 공부를 많이 했었는데,
시간을 기록할 수 있는 깔쌈한 타이머가 없었고 만들고나서 이걸 쓰면 되겠다는 생각도 하였습니다.


군대에서의 개발

군대에서의 개발은 정말 쉽지 않았습니다.

군인 특성의 부족한 시간은 딱히 문제가 되지 않았습니다.

현재 현업에 종사하시는 개발자 분들도 야간에 시간을 내어 토이 프로젝트를 진행하고 있고...

저 역시 같은 처지에 놓여있다 생각하여 시간은 그리 큰 문제가 되지 않았으나…


문제는 개발 환경 에서 찾아왔습니다.

일단 군대 사이버지식방(사지방)의 PC로는 VSCode가 제대로 동작하지 않았거니와,

보안상 터미널도 막혀있어 지금까지 해온 개발 습관과 지식으로는 안되겠다 판단,

개발 전부터 큰 난관에 부딪히게 되었습니다.


물론 구름, Code Sandbox과 같은 Web IDE를 사용하면 문제는 말끔히 해결되겠지만,

저는 생고집을 부리더라도 VSCode를 사용하고 싶었습니다.

저한테 가장 익숙했고, 나가서도 그 툴을 사용하고 싶었기에 더 익숙해지고 싶었죠.


결국 수 일의 구글링 끝에 AWS의 EC2 인스턴스를 하나 구매하여,

그 위에 웹에서 작동하는 VSCode인 code-server를 구축함으로써

편하게 VSCode의 기능들을 사용할 수 있게 되었습니다.

(실제 브라우저로 EC2에 접속시 보이는 화면입니다. 정말 만족스러웠네요.)


개발 준비를 해봅시다

일단 메인 스택은 Next.js로 정했습니다.

그 이유는 2가지 였는데,

  • SSR이 CSR과 어떤 차이가 있는지, 이게 체감이 되는지 직접 보고싶었음
  • 단순하게 그냥 써보고 싶었음 (약간 Next.js는 필수라고 생각했던 것 같음)

지금까지 Next.js는 강의를 통해서만 컨셉을 배웠었고, 그냥 강의에서 제시해주는 프로젝트만 따라가다보니...

마치 머리속의 지식이 비눗방울 같달까요?

톡 건드리면 사라질거 같고 대충 어떻게 만지면 될지 형태는 알겠는데, 속은 텅 비어있는 느낌이었어요.

그래서 이 기회에 한 번 써보자! 라는 마인드로 Next.js를 골랐던 기억이 있네요.


함께 CSS-in-JS 라이브러리로 Emotion을 가져왔는데,

CSS module, styled-js는 제 취향이 아니었고

styled-components는 Next.js에서 여러가지 세팅이 필요했었습니다.


그에 비해 Emotion은 styled-components의 대부분의 기능을 지원함과 동시에

.babelrc 파일을 통해 플러그인만 작성해주면 세팅이 완료되기에

Emotion이 적격이라 판단했습니다.


그리고 너무 편한 Typescript도 가져와서 개발을 진행하게 되었습니다.

이렇게 준비물을 다 가져오고 만들었던 프로토타입을 기반으로

개발을 시작하게 되었습니다.


개발... 개발.... 또 개발...

React 관련해서 배웠던 것들

이번 프로젝트를 통해 정말 많은 지식들을 얻게 되었는데,

가장 신선했던 것은 React의 함수형 프로그래밍 철학(순수성)과,

무엇보다도 useEffect 는 다른 변수와 동기화될때 가장 유용하게 사용된다는 것이었습니다.


지금까지 저는 useEffect 를 대할 때,

아래 두 가지 생각을 가지고 사용했는데요.

그냥 컴포넌트가 render 되었을 때 실행시킬 용도로 가장 많이 사용하겠지.

의존성 배열에는 그냥 effect 안에서 사용하면 무지성으로 넣어주는게 원칙이지.


그런데

왜 strict 모드일 때 useEffect 가 2번 실행될까?

라는 의문에서 시작하여,

React가 추구하는 컴포넌트 순수성에 대해 이해하게되고,

useEffect 를 render 되었을 때 실행시킬 용도로 사용하는 것은 굉장히 좋지 않은 것이라는 결론을 내렸습니다.


useEffect는 상태와 맞물려 사용하는게 좋다.

그렇게 뒤따르는 궁금증이 생겼는데,

그럼 useEffect를 어디에 씀?

이었죠.

프로젝트를 진행하며 직접 느낀 이에 대한 저의 대답은,

“ 컴포넌트의 상태와 맞물려 사용할 때 가장 베스트다. ”

라고 결론을 내렸습니다.


여기 상태(state) 하나와 effect 하나가 있습니다.

단순하게, 상태 값이 변할 때마다 effect 가 실행될텐데요,

제가 바라본 핵심은 state 의 값에 따라 effect 내부에서 다른 로직을 실행시킬 수 있다는 겁니다.


이 컨셉을 더 응용하면,

상태를 통해 연쇄적으로 서로 다른 effect 로직을 실행하여 관심사를 분리해낼 수 있다는 것도 발견하였고

이 컨셉을 프로젝트에 적극적으로 사용했던 것 같습니다.


의존성 배열에 아무거나 막 넣어도 될까?

이런 관점에서 useEffect 를 대하다 보니 앞서 말했던,

의존성 배열에는 그냥 effect 안에서 사용하면 무지성으로 넣어주는게 원칙

에도 의구심이 생겼는데요.


이런 방식으로 개발을 진행하면

의도치 않은 effect 실행을 야기할 수 있다는 생각을 하게 되었습니다.


문제 상황

위 코드는 개발자가 stateA 의 변화를 감지하기 위해 만든 effect 입니다.

그리고 이 로직은 stateB 의 값에 따라 실행할지 말지 결정하게 됩니다.


이 상황에서 발생한 문제는 effect 에서 stateB 가 사용된다고 무지성으로 의존성 배열에 넣게되는 경우인데,

stateBtrue 로 변화했을 때도 위 로직이 의도치 않게 실행된다는 겁니다.


결국 개발자의 의도는 stateA 의 변화에만 대응하려고 했는데,

졸지에 stateB 의 변화도 감지하게 된 것이죠.


어떻게 해결할까?

이 문제를 어떻게 개선할지 고민하다가

그냥 useEffect 밖으로 빼버리면 해결되는 문제라고 생각했습니다.


그 과정은 다음과 같은 생각의 흐름이었습니다.

Q. stateB 를 왜 의존성 배열에 넣었음?
A. 단순히 값의 최신상태를 보장하기 위해서.

Q. 이 문제를 해결했을 때 코드가 어떻게 변해야 함?
A. 의존성 배열에서 stateB 가 없어야 함.

Q. 그럼 effect 밖에서 stateB의 최신상태를 보장하는 방법이 있음?
A. 아 그냥 로직 자체를 effect 밖에서 arrow function 으로 구성하면 되겠네.

문제가 말끔히 해결되었습니다!


만약 effect 밖으로 뺀 로직의 비용이 크다면,

useCallback 의 사용을 통해 선택적 최신화를 고려해볼 수 있겠습니다.


재밌는데?

개발을 진행하면서 이러한 컨셉들에 대해 굉장히 많은 고민과 연구를 했고

계속해서 최적의 답을 찾아나섰습니다.


가끔은 진짜로 자다가 꿈에서 해답을 찾은 적도 있었고

더 나은 컨셉이라고 생각된다면 과감하게 이전 코드를 전부 지워버리고

새로운 코드로 다시 짜곤 했습니다.


굉장하게 어두운 밤에 항해를 하는 기분이었는데,

그래도 너무 즐거운 시간들이었습니다.


실시간으로 성장한다는 것이 피부로 느껴지고,

왜 개발자가 토이 프로젝트를 진행해야 하는지 몸소 느꼈었던 것은

아직도 좋은 경험으로 남아있습니다.


그렇게 첫 타이머를 완성하다

우여곡절 끝에 타이머라고 부를 수 있는 무언가가 나왔습니다!


제가 추구했던 디자인 철학

제가 추구하는 디자인은 plus design이 아닌 minus design인데요,

예전 프로젝트들에서는 그냥 버튼이나 기능들을

최대한 섹션안에서 보여주기 위해 우겨넣는 디자인을 했었습니다.


그런데 그러고보니까 시각성도 떨어지고

모던한 디자인을 하기도 힘들거니와, 한다고 하더라도

그 디자인이 오래갈 디자인처럼 보이지는 않았습니다.

물론 제 실력이 부족한 것이 가장 컸던 것 같지만요.


최근에는 이러한 문제들 때문에

과감하게 요소들을 제거하는 디자인을 선호합니다.

위 프로젝트 결과에서도 보이듯이,

결과물이 굉장히 무언가 허전합니다.


허전하지만 필요한 요소들만 추려서

알맞게 떨어지는 레이아웃안에 넣으려고 굉장히 노력을 했고

그 결과 허전함에도 깔끔하고 시각화가 잘 되어있는 느낌을 줍니다.

그렇게 보였으려나요?


트랜지션에도 많은 신경을 썼습니다

또한 저는 인터랙션을 중요시 여기다보니,

인터랙션을 통한 요소들의 트랜지션에도 굉장한 노력을 기울였습니다.


가장 노력을 기울여야 했던 핵심 문제는

어떻게 하면 시선 분산을 막고 타이머에 집중하게 할 수 있을까?

였습니다.


이런 문제는 저의 철학인 minus design과 섞여서

타이머에 집중해야 될 때는 다른 요소를 다 제거해버리자.

라는 결론에 도달했습니다.


거기에 더불어,

제가 존경하는 메이커 김종민님에게서 배운

트랜지션/애니메이션을 만들 때 연속되는 무언가를 이용하면 좋다.

를 이용하여,


타이머 인터랙션이 실행되면 작았던 시간이 그 자리에서 자연스럽게 커지면서

사용자로 하여금 강조되게하는 트랜지션을 구상했습니다.

따라서 아래와 같은 타이머 트랜지션이 나올 수 있었습니다.


이제 기능을 추가해보자

여기서 끝내면 이 프로젝트만의 개성이 없었습니다.

분명 웹이기 때문에 가능한 것들도 있을 것이고,

좀 더 도전해보고 싶었습니다.


그래서 가장 먼저 추가한 기능이

종료시 알림기능 입니다.


종료시 소리 알림은 타이머 특성상 기본으로 넣어야 한다고 생각했고,

혹여나 사용자가 창을 잠시 닫았더라도 종료시에 백그라운드 알림이 왔으면 좋겠다고 생각했습니다.


오디오가 원할 때 실행이 안 되는데요?

웹에 오디오를 넣는 것은 그렇게 어려운 기능이 아닙니다.

딱 한 가지만 고려하면 되는데요,

바로 브라우저의 보안 정책입니다.


오디오와 관련해서 각 브라우저별로 제시하는 정책은 상이하지만,

대체적으로 오디오 재생이 허용되는 공통적 조건은 아래와 같습니다.

  • 음소거 / 오디오 볼륨이 0
  • 사용자와의 인터랙션
  • 화이트리스트에 등록된 사이트 (브라우저 판단)
  • Feature-Policy 설정

위 조건중 하나라도 만족하면 되는데,

저는 사용자와의 인터랙션 항목에 집중하여 개발을 진행하였습니다.


사용자와의 인터랙션?

단순히 클릭, 터치, 키 입력 등의 이벤트 발생을 말합니다.

이렇게 이벤트가 발생했을 때, 이벤트 핸들러를 이용하여 오디오를 실행하는 코드를 구성하면 간단하게 오디오를 실행할 수 있습니다.

그런데 문제는 ‘인터랙션 이후의 실행’ 에 대해 굉장히 까다롭다는 점인데요.


문제 상황

저 같은 경우는 타이머를 click 인터랙션으로 시작하고 나서

타이머가 종료되었을 때 오디오를 실행하게 되는데,

여기서 타이머가 종료된 시점에서는 브라우저가 이미 인터랙션이 종료되었다고 판단하여

오디오를 실행시키지 않던 문제가 있었습니다.


대략적으로는 아래 코드와 비슷한 상황입니다.

이와 관련하여 여러가지 편법을 연구했지만,

이에 대하여 브라우저마다 처리가 다른지

어떤 브라우저에서는 작동하지만, 다른 브라우저에서는 작동하지 않던 문제가 있었습니다.


해결 방법

이 문제를 해결하기 위해 사용한 핵심 컨셉은 이겁니다.

이미 인터랙션을 통해 실행되었던 audio 노드의 소스를 바꿔버려 재실행시키면 정책에 걸리지 않는다.


이 컨셉에서 착안하여 다음과 같은 해결 방법을 사용했습니다.

  1. 사용자 인터랙션 발생시, 매우 짧고 소리도 들리지 않는 오디오를 실행한다.
  2. 해당 오디오가 끝나면 실제로 재생할 오디오로 소스를 바꿔버린다.

이런 방식으로 나중에라도 원할때 오디오를 실행할 수 있도록 로직을 구성했습니다.

(얼추 비슷한데, 사용한 실제 코드는 아니고, 설명용입니다)


백그라운드 알림을 넣어보자

백그라운드 알림을 넣기 위해 많은 컨셉들을 공부했었습니다.

그 중에서 가장 신기했던 것이 Service Worker 라는 것인데,

특정 스크립트를 백그라운드에서도 작동하게 할 수 있다는 것을 보고 굉장히 감탄했었습니다.


또한, Firebase가 제공하는 Cloud messaging을 이용하여

백그라운드 알림을 제공할 계획을 세웠습니다.

Cloud messaging 문서에서 제시하는 Service worker 코드를 참고하여

messaging token을 부여받고, 테스트를 하려는 찰나...


? 왜 알림이 안오지?


군대라는 환경의 한계

제가 개발하는 사지방의 환경에서는 브라우저 알림을

군 정책상 기본적으로 막아놨던 것을 깨달았습니다…

따라서 이 기능에 대한 데스크탑 환경에서의

테스트 및 개발이 군 환경에서는 불가능했습니다.


이렇게 이 기능은 추가하지 말아야되나 생각을 하곤 했습니다.

그래도 어떻게든 완성시켜야겠다는 생각에

아껴두던 휴가를 주말 토요일 일요일 이렇게 2일정도 써서

집에서 날을 새며 개발하고 또 개발하고…

어떻게든 복귀전까지 기능을 구현하고자 했던 기억이 있네요.


결국 긴 삽질 끝에 기능을 추가하는데 성공하고

백그라운드 알림이 잘 오는 것을 확인했습니다.

( 허나 이 기능은 아직 안정화 되지는 않아서 개선이 필요한 부분입니다 )


백그라운드 알림을 지원하지 않는 브라우저라면?

또한 이 기능은 모든 브라우저에서 지원하지 않기 때문에,

현재 브라우저가 지원하지 않는 브라우저인지 탐지하는 로직을 구성하였습니다.


백그라운드 알림 옵션을 활성화 시켰을 때, 브라우저가 지원하지 않는다면

아래와 같은 모달창을 띄우도록 하는 개발을 진행하였습니다.

지원하는 브라우저, 지원하지 않는 브라우저의 리스트를 만들어서

한 눈에 어떤 브라우저가 지원하는지 보기 쉽게 제작했습니다.


오디오를 미리 들어볼 수 없을까요?

저는 다음날 일찍 일어나야 할 일이 있을때마다 알람을 맞추곤 하는데요.

군에서는 핸드폰으로 알람을 맞추기 힘드니,

적당한 손목 시계를 사용하곤 합니다.


그런데 군대 생활관은 저 혼자 쓰는게 아니기 때문에

이 시계의 알람이 민폐가 될 수 있습니다.


그래서

미리 시계 알람 소리를 들어보고 소리를 조절할 수 없을까?’

라고 생각하던 찰나,


이 기능을 제 프로젝트에도 적용해야겠다는 생각을 했습니다.

미리 들어보지 못하고 알람기능을 켤지 말지 선택지를 주는 것은

사용자 경험에 있어서 굉장한 불편함으로 다가올 것이라 생각했습니다.


따라서 앞서 제작한 모달창을 재사용해서

오디오를 미리 들어볼 수 있는 기능을 제작했습니다.

모달창 하단의 버튼을 누르면

알람 소리를 미리 들어볼 수 있습니다!


기능이 점점 추가되는데요?

이 외에도 넣고 싶었던 많은 기능을 넣었습니다.

  • 타이머 최대 시간 변경
  • 타이머 색상 변경
  • 한국어, 영어 토글하기
  • 분/초를 퍼센트로 표시하기

등등…


그런데 이런 기능이 추가되다보니

점점 공간이 부족해졌습니다.


따라서 메뉴를 제작해야함을 느끼게 되었습니다.


그래서 메뉴를 만들었습니다.

메뉴는 구글의 Material You의 디자인을 참고하여 제작했습니다.


모바일 메뉴

그러나 위의 메뉴 디자인은 모바일 환경에서는

불편한 디자인으로 다가올 수 있습니다.


상대적으로 화면의 너비가 부족한 모바일 환경 특성상,

위의 고정 메뉴바는 화면의 너비를 꽤나 잡아먹는 요인이 되어

다른 중요한 요소를 더욱 강조해야하는 것을 힘들게 합니다.


따라서 모바일 메뉴를 따로 제작하기로 결정했습니다.


모바일 우선 디자인의 중요성

그러나 이 과정에서 뼈아픈 경험을 했는데,

바로 모바일 우선 디자인의 중요성입니다.


데스크탑 디자인을 먼저하고, 모바일 디자인을 나중에 하게되니

넓은 화면과 많은 기능을 가진 데스크탑 디자인을

작은 화면의 모바일 디자인 속으로 우겨넣는 느낌이 강하더라고요.


그래서 두 개의 디자인이 굉장히 일관성 없다는 느낌을 받았고,

이 간극을 최소화하기 위해 많은 노력을 기울였습니다.


만약 모바일 우선 디자인을 진행하였다면,

훨씬 수월하게 반응형 디자인을 구상하지 않았을까 생각했던 것은 값진 경험이었습니다.


썼던 기록, 다 저장해드려요

타이머를 만들고 나서 다른 분들에게 소개를 했던 적이 있었습니다.


제 타이머를 보시고 어떤 한 분께서,

라는 피드백을 주셨습니다.

재밌는 기능처럼 보여서 바로 개발에 착수했습니다.


Localstorage vs IndexedDB?

브라우저에 어떠한 값을 반영구적으로 저장하는 방법으로는 많은 방법들이 있지만,

이 프로젝트에서 데이터 저장을 위해 채택한 방식은 IndexedDB 입니다.


LocalStorage의 단점 중 하나로, 극히 적은 저장 용량을 꼽을 수 있는데요.

이 프로젝트에서는 타이머를 썼던 기록이 상당히 많아질 수 있으므로,

LocalStorage의 저장 용량으로는 언젠가 한계가 드러날 것이라 예상했습니다.


따라서 저장 용량이 상대적으로 매우 많은 IndexedDB를 사용하여

데이터 값을 반영구적으로 저장하기로 결정했습니다.


기록 페이지를 만들어야죠?

타이머를 사용한 기록들을 보여줄 페이지를 만들었습니다.


이 기록 페이지는 꽤나 공들여서 제작했던 것 같습니다.

뭐 추가하자... 뭐 추가하자...

이 페이지 하나 만드는데만 3주 이상 걸렸던 기억이있네요.


기획

이 페이지를 기획하던 당시,

타이머 사용 데이터들을 사용자들에게 어떻게 가공하여 보여줄지에 대해 많이 고민했었습니다.


우선, 타임라인 형식으로 데이터를 시간 순으로 나열해주는 페이지를 생각했었습니다.

그런데 막상 이렇게만 보여주자니 너무 단조롭더라고요.


좀 더 데이터를 쌓는 의미를 부여하고 싶다.

사용자의 데이터를 이용해 추가적인 경험을 주고 싶었습니다.


그래서 생각한 것이, ‘개요(Overview)’ 섹션입니다.

이 섹션에서는 사용자의 데이터에 통계적인 의미를 부여하고자 했습니다.

  • 특정 기간동안에 사용한 타이머 시간
  • 사용자가 어떠한 방식으로 타이머를 사용하는 지

등등을 말이죠.


이러한 데이터들을 가공하여 시각적으로 잘 나타낸다면,

충분히 개성있는 페이지가 될거라 생각했습니다.


어떻게 디자인할 것인가?

예전부터 CSS의 flexbox를 사용해보면서 한 가지 생각이 있었습니다.

flexbox의 특성 중 하나는 ’자식들이 너비에 따라 늘어지고 줄어듬‘ 이잖아요?

이 컨셉을 이용하여 예전부터 섹션이 변화하는(토글되는) 디자인을 구성해보고 싶었습니다.

( 예전에 그려놨던 아이디어 노트. 너무 못그린듯? ㅋㅋㅋㅋ )


그런데 마침 제가 기획했던 섹션 구성에 이 디자인이 딱 들어맞았습니다.

바로 프로토타입을 만들어본 결과,

이걸 원했다...

이 컨셉을 핵심으로 가지고 가기로 결정했습니다.


핵심 컨셉이 잡히고 나니, 각 섹션들의 디자인도 각이 잡히기 시작했습니다.

각 섹션에 어떤 요소들을 집어넣을 지는 미리 기획 단계에서 생각을 해두었고,

나머지는 디테일의 영역이었습니다.


가령 이 섹션에서 어떤 것을 강조하고 싶은지에 따라,

색상이나, 폰트 종류/크기/굵기, 여백 등

최대한 섬세하게 조절했습니다.


섬세함?

여기 타이머를 특정 기간동안 얼마나 사용했는지를 나타내주는 지표가 있습니다.


이러한 통계적 지표를 보게된다면

사용자는 이 값의 크기를 인식하기 위해 ‘단위’에 집중하게 되는데요.

여기서 값의 단위는 시간(Hours) 입니다.


따라서 사용자로 하여금 ‘단위가 나타내는 값’ 을 더욱 강조하고자,

시간(Hours) 부분의 폰트를 분(Minutes)을 나타내는 영역 보다

더 굵고 크게 만들었습니다.


이 외에도 사용자 경험 측면에서 계속해서 생각하면서 넣게된

섬세함들이 정말 많다고 생각합니다.

이런 생각 하나하나가 완성도를 끌어올리는데 정말 중요한 역할을 하는 것 같습니다.


애니메이션도 중요하죠?

애니메이션/트랜지션은 완성도를 높일 때 사용하기 좋은 도구입니다.

저 같은 경우에는 Fade-in-out 애니메이션을 정말 좋아하는데요.


Fade-in-out 애니메이션은 단순하다는 특징이 있어

자칫하면 사용자로 하여금 단조롭다는 인상을 주기 마련이며,

심하면 사용자 경험 측면에서 오히려 단점이 될 수 있습니다.


그러나 이는

  • 요소간 딜레이 차이
  • 적절한 물리 현상을 고려한 easing-function
  • 불편하지 않은 정도의 duration

이 3가지로 충분히 극복가능한 범위라고 생각하고,

잘 활용한다면 오히려 전체적으로 세련된 인상을 줄 수 있습니다.

특정 요소를 강조하는데도 딱이고요.


그래서 전체적으로 애니메이션 파라미터들을 적절히 조율하여

위와 같은 애니메이션을 구성했습니다.

또한, 앱 전체적으로 일관성을 주기 위해 아래에서 떠오르는 Fade-in 애니메이션으로 통일했습니다.

어떠신가요?


마지막 피날레, PWA

프로젝트를 어찌저찌 만들고 나니

욕심이 생겨 앱으로도 만들고 싶어졌지만

군 환경에서는 사실상 불가능에 가깝기 때문에 포기하려던 찰나,


최근 유튜브에서 본 PWA 관련 영상이 떠올랐습니다.

PWA 쓰면 데스크탑/모바일 앱처럼 쓸 수 있다던데?

라는 생각을 가지고 PWA의 결과물을 봤는데…


제가 원하는 결과물에 가까웠습니다.

그래서 바로 PWA 개발에 착수했습니다.


고마워요, next-pwa!

정말 고맙게도 이미 누군가가 만들어놓은

next-pwa 라이브러리가 있었고,

이를 이용하여 PWA의 Service Worker 구성은 손쉽게 끝날 수 있었습니다.


덕분에 저는 manifest 구성에 몰입할 수 있었고,

manifest에 필요한 로고들을 부족한 실력으로 전부 그렸습니다.

( 실제 제가 만들어 사용한 favicon )


벡터 그래픽에는 거의 문외한이다보니 만드는게 쉽지는 않았지만,

어릴 때부터 그림그리기를 좋아했는데,

이런 분야에서 그림을 그리게 되었다는 생각에

막막했었다기 보다는 신났었던 기억이 있네요.


그러다보니 생각보다 쉽게 PWA를 만들었고,

너무나 만족스러운 결과물이 나와 기분이 좋았습니다!

( IOS에 깔린 제 프로젝트 )


SEO?

배포할 시점이 다가오니, SEO 관련해서 고민을 하게 되었습니다.


근데 생각해보니 컨텐츠가 적은 제 프로젝트 특성상 SEO가 의미가 있긴 한가...

라는 생각이 들더라고요.


그래서 별건 아니지만,

그냥 지식습득 용도로 몇 가지 기능을 추가했습니다.


Sitemap 제출 및 Robots.txt

구글 검색엔진 크롤러를 돕기위해 구성했습니다.

next-sitemap 이라는 라이브러리가 동적 생성을 도와주더라고요.

덕분에 편하게 구성했습니다.


웹 사이트 공유하기

그냥 이건 연습삼아 재미삼아 만든 기능아닌 기능인데,

단순하게 SNS에 링크를 공유하면 카드가 뜨게 만드는 겁니다.


간단하게 meta tag를 추가함으로서 제작이 가능했고,

결과물도 만족스럽게 나온 것 같습니다.

(디스코드)(카카오톡)


결론 & 내 생각

우선 여기까지 와주신 모든 분들께 감사드립니다.


근 3개월동안 정말 재밌는 시간이었습니다.

그만큼 배운것도 많고 버려야할 것도 많았습니다.


항상 느끼지만 개발이란 분야는 정말 신기하고 새로운 것 같습니다.

아무래도 항상 무언가로부터 배워야하는 직종이기 때문일까요.


그렇기에 한편으로는 정말 무섭기도 합니다.

아직 난 이정도의 간단한 토이 프로젝트밖에 못하는데,
실제 현업에서 인정받으면서 뛰려면 얼마나 많은 노력을 해야하는 것일까?

라곤 종종 생각하기도 합니다.


오랜만에 제가 처음 웹 개발을 배울 때, 다른 곳에 썼던 프로젝트 회고글들을 읽어보니

굉장히 무언가 작은 것을 배운다는 것에도 들뜨고 신났던 제가 있네요.


물론 지금도 그런 기분이 들고 무엇을 배우게 될지 기다려지기도 합니다.


하지만 얕아보이는 바다에 다이빙을 했는데

막상 잠수해보니 끝이 없을 정도로 어두운 심해가 펼쳐진 기분이랄까요.

그런 심해속에는 배워야할 것도 정말 많고, 해결해야 할 문제도 정말 많다고 생각합니다.


저는 개발자는 개발하는 것도 중요하지만,

무언가를 만들어가는 과정에서 발생하는 문제를 해결하는 사람이라고도 생각합니다.

그렇게 문제를 해결하다보면 제가 만들고자 했던게 만들어져 있을테니까요.


신에게 감사하게도 저는 아무래도 이런 과정을 진심으로 즐기고 재밌어하는 사람인 것 같습니다.

그래서 개발자가 천직인거 같기도 하고요.


이번 프로젝트를 끝내고

혼자 이런저런 내용들을 생각해보았는데요.


뭔가 글로 털어내고 싶었습니다.

그렇기에 제가 지금 여기서 날을 새면서 글을 쓰고 있는 거 같습니다.


긴 글 읽어주셔서 정말로 감사합니다.

좋은 하루 되세요.

profile
중괄호로 뭐든지 만듭니다.

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN