Cometin'

디프만 랜딩 페이지 개발기

2023-03-17 at Project category

디프만 랜딩 페이지

디프만은 디자이너와 프로그래머가 만났을 때의 줄임말로, 직장인과 대학생을 대상으로 서비스 개발과 성장을 목표로 진행하는 동아리다.

운이 좋게도 11기에 참여할 수 있게 되었고 22년 하반기부터 시작된 12기와 23년도 상반기에 시작될 예정인 13기의 운영진을 맡게 되었다.

운영진으로써 참여하는 이유들 중 웹 개발자와 디자이너 직군에게는 큰 매리트(일 수도 있는)가 하나 있는데, 바로 오늘 동아리의 랜딩 페이지를 리브랜딩하고 개발하는 것이다.

나 또한 개발자로써 사이드 프로젝트 중 가장 많은 사용자를 접할 것이라 생각했기에 기대하며 운영진으로써 참여하였고

두 기수의 랜딩 페이지를 개발하며 겪은 점을 공유하고자 한다.

스캐폴딩

12기의 랜딩 페이지를 개발할 때 가장 먼저 고민한 점은 기존의 구조를 따라갈지, 혹은 새로 스캐폴딩할지 였다.

기존의 구조는 그때 당시 접해보지 않았던 앵귤러의 모듈 기반과 비슷한 구조였어서 흥미로웠지만, 결과론적으로 새로 스캐폴딩하는 선택을 하였고 이유는 다음과 같다.

랜딩 페이지의 특성

엄청나게 많은 경험이 있지는 않지만, 외주 개발을 하였을 때 상당수가 랜딩 페이지 개발이였다.

그렇기에 비즈니스 로직이 거의 없다시피한 랜딩 페이지에 기존의 구조와 코드 스타일을 따르는 것은 소모되는 리소스에 비해 이점이 없다고 생각되었다.


또한 리브랜딩이 되어 모든 디자인과 구성이 달라져, 이전의 구조가 이번 기수의 랜딩 페이지에도 적합할 지는 장담할 수 없었다.

마감 기간

많은 지원자들과의 약속인 모집 기간 일정에 맞추어 개발이 진행해야 되었고,

디자인에 소모되는 일정을 파악하지 못했던 우리에게 주어진 개발 기간은 채 4일이 되지 않았다.

본업으로써 개발을 하는 것이 아닌 모두가 여가 시간을 활용해서 개발을 진행해야 되었기 때문에 굉장히 촉박한 일정이라 생각되었고

이러한 이유로 이전 구조에 맞추어 개발하는 것보다 새롭게, 우리가 편한 방식대로 개발하는 것이 일정을 맞출 수 있는 유일한 방법이라 판단하였다.

유산

새롭게 프로젝트를 구성하지만 서비스 정보는 이전의 프로젝트에서 가져와 사용하였다.

여기서 말하는 서비스 정보는 이전 기수에서 개발한 서비스들의 이미지와 설명, 개발자명과 같은 정보들이다.

이전 기수가 적지 않으며 연락할 수 있는 채널이 따로 존재하지 않기에 재사용은 피할 수 없는 선택이였다.

이미지 형식

이전 기수의 정보들을 확인하며 이상한 점이 한 개 존재하였는데, 서비스의 로고가 아닌 이미지들도 svg 파일로 관리되고 있었다.

svg의 경우 화려할 수록 (요소가 많을 수록) 파일의 크기가 커진다.

확인해 본 결과 이미지의 크기가 메가바이트 단위였고, 그로 인해 이미지 로드에 굉장한 시간이 소모되었다.

11기 프로젝트 페이지 라이트하우스

물론 이미지 파일이 굉장히 많았지만, 이는 필히 언젠가는 수정해야할 과제라고 생각되어 약 150개의 이미지를 svg에서 png로 변환하였다.

당시에는 webp와 같은 최신 포맷을 알지 못했다.

12기 프로젝트 페이지 라이트하우스

이를 통해 많은 지표를 개선할 수 있었고, 노가다성이 짙은 작업이였지만 동아리와 동아리에 관심이 있는 많은 사람들에게 기여한 것 같아 기억에 남는다.

정적 사이트

이미지를 포함한 서비스들의 정보는 상수로써 관리되고 있었다.

Next.js 환경이였기에 이는 페이지별로 정적으로 생성될 수 있음을 의미하지만 그렇지 않았고, 클라이언트 사이드에서 처리되고 있었다.

물론 우리와 같이 촉박한 혹은 더 촉박한 일정이셨을 확률이 다분하고

12기 또한 1차 배포 이후에 SSG를 적용했기에 나무랄 생각은 없고 오히려 운영에 고생하셨음을 알기에 감사한 마음이 크다.

빠른 페이지 로드로 사용자 경험을 증진시키며, 검색 엔진 최적화를 통해 더욱 많은 사람들이 동아리를 접할 수 있음을 이유로 작성된 상수를 이용해 SSG로써 개선하였다.

관련한 지표를 이미지로 남겨두진 않았지만, TTI를 0.4초, LCP를 1.5초 감소시킬 수 있었다.

모니터링

위에서 언급했듯이 동아리 랜딩 페이지를 개발을 하고 싶었던 이유는 많은 사용자를 접한다는 것이다.

하지만 얼마나 많은 사용자가 접하는 지, 검색 키워드는 무엇인지 알 수 있는 도구들이 부착되어 있지 않았다.

이는 굉장히 많은 지표의 손실과 더불어 '지표가 없는 개선은 나침반없는 항해'라는 말에 공감하는 나에게는 필히 부착이 필요하다고 생각되었다.

사용자 모니터링

종합적인 사용자 지표 확인을 이유로 GA를 부착하였고,

히트맵과 녹화 등 더욱 세부적인 사용자 지표 확인을 이유로 Hotjar를 부착하였다.

디프만 hotjar

부착 이후 쌓인 지표를 사용해 모집 기간 마감 이후 기능 추가를 계획하는 등, 동아리 운영에 기여할 수 있었어서 기억에 남는 경험이 되었다.

서치 콘솔

지금 구글에 '디프만'을 검색하면 가장 위에 랜딩 페이지가 위치한다.

물론 CTR1이 높아서 그렇겠지만 이렇게 디프만을 찾는 사람들은 얼마나 있는지,

다른 어떤 검색어로 노출이 되는지, 그 비율의 노출수는 얼마인지 확인할 수 있다면 좋겠다고 생각했다.

그렇기에 구글 서치 콘솔에 등록하였다.


등록은 GA 부착을 선행하였기에 쉽게 할 수 있었지만, 사이트맵이 존재하지 않아 메인이 아닌 많은 페이지들이 검색 엔진에 노출되고 있지 않았다.

이를 해소하고자 Next.js의 SSG로 만든 사이트들의 사이트맵 생성을 자동화해주는 next sitemap을 사용해 서치 콘솔에 제출하였다.

디프만 서치 콘솔

사실 SSG 사용과 서치 콘솔을 리드한 가장 큰 이유가 위 사진 때문인데,

위 사진처럼 디프만에서 개발된 서비스를 검색했을 때 디프만이 노출되게 하고 싶었다.


검색 엔진이 늘 그렇듯 즉각적으로 효과를 볼 수 있진 않았지만, 약 반년이 지난 지금은 게재 순위가 1위인 서비스도 있고 이를 통해 노출과 클릭이 되고 있어 뿌듯한 감정이 크다.

인터랙티브

내가 동아리 랜딩 페이지를 개발하며 가장 넣고 싶었던 것이 인터랙션이다.

인터랙티브함으로써 사용자에게 더욱 큰 인상을 남길 수 있을 것이라 생각하였고, 무엇보다 내가 인터랙티브한 서비스를 좋아하기 때문이다.

디프만 12기 인터랙션

다른 사이드 프로젝트에서 경험했듯이, 인터랙션까지 디자인을 받진 않았지만 내가 보기에 디자인과 잘어울리는 방향으로 추가하였고 다행히 디자이너분들에게 긍정적인 피드백을 받을 수 있었다.


물론 인터랙션을 넣어 지표로써 긍정적인 영향을 미쳤는지는 확인할 수 없지만 더욱 내 마음에 드는 랜딩 페이지를 만들 수 있으면서 인터랙티브 디자이너(?)로써 인정받을 수 있었던 경험이라 기억에 남는다.

스캐폴딩 two

위 내용까지가 12기 랜딩 페이지를 개발하면서 겪은 경험이고, 지금부터는 그나마 최근인 13기 랜딩 페이지를 개발하며 겪은 경험을 공유하려 한다.


이번에도 동일하게 새로운 브랜딩으로 개발이 진행되어야 했고 똑같이 스캐폴딩을 할지 고민이 되었다.

결과부터 말하자면 기존 12기의 구조를 선택하게 되었는데 이유는 다음과 같다.

인력과 일반적

13기 랜딩 페이지를 개발하는 인력에 나를 포함해 12기 랜딩 페이지를 개발한 운영진이 2명이 있었으며,

다소 일반적이라고 생각되는 구조를 사용했기에 다른 개발자분들께서도 무리가 없을 것이라고 판단하였다.

디프만 13기 리뉴얼 시작

물론 무리는 아니지만, 적응이 힘들 수도 있다고 생각되었기 때문에 리뉴얼 베이스 브랜치를 드래프트로 띄운 PR에 작업 시에 궁금할 만한 혹은 사용했던 것들을 적음으로써 해소하고자 노력했다.

부분적 재활용

스캐폴딩을 새로하진 않았지만, 랜딩 페이지의 주가 되는 퍼블리싱은 새롭게 작업하였다.

그렇게 한 이유는 랜딩 페이지의 특성상 기능이 있는 컴포넌트는 거의 없으며,

기존에 디자인이 비슷한 컴포넌트가 존재하더라도 수정하는 행위보다 새로 만드는 행위가 리소스가 덜 들것이라고 판단하였기 때문이다.

이전 에셋 확인 방법 PR

물론 아예 삭제하지는 않고,따로 디렉토리를 분리하고 tsconfig, eslint 세팅을 통해 빌드 과정에서 제외시켜 참고할 수 있도록 하였다.


그렇게 이전의 것을 유지하는게 효과적인 것은 유지하며,

새롭게 만드는 것이 효과적이면 새롭게 만들 수 있도록 환경을 구성했다.(고 믿는다)

성능

디프만 12기 지표

12기 홈

위의 12기 라이트하우스 지표 또한 만족스럽지 못하다고 생각한 사람들이 많을 것이다.

물론 나 또한 그럤고, 이를 해결하고 싶었다.

디프만 12기 이미지 로드

12기 성능 측정

성능 측정을 한 결과 이미지 로드에서 굉장한 시간이 소모되고 있었고 랜딩 페이지 특성상 이미지가 아니면 성능을 잡아먹는 요소도 없었기에 이것만 해결된다면 상당 부분 개선될 것이라 생각하였다.


개선 방법은 위에서도 언급한 적이 있는 webp 포맷을 사용하는 것이라 생각되었는데,

실제로 피그마에서 동일한 이미지를 내보내기 했을 때 용량 크기가 6배에 가까웠기 때문이다.

스크린샷 2023-03-17 오후 11 46 12

13기 측정 결과

스크린샷 2023-03-17 오후 11 39 11

13기 홈

스크린샷 2023-03-17 오후 11 38 34

13기 프로젝트

절대적인 크기가 감소했기에 그에 비례하게 요청 응답 시간이 감소했고 여러 방면에서 이전에 몰랐던 것들, 미처 신경을 쓰지 못했던 것들을 적용해 전체적인 지표를 개선할 수 있었다.

코드로써의 성능 개선을 위해 Next.js의 dynamic import, Framer-motion의 lazyMotion 등을 사용했다.

인터랙티브 two

13기 랜딩 페이지를 확인한 분들은 이전보다 인터랙티브하지 않다고 생각할 것이다.

이것은 현재의 디자인에 어울리지 않으며, 내가 너무 인터랙티브한 것이 촌스럽다는 생각으로 바뀌었기 때문이다.

트렌드의 영향인지, 과유불급을 깨달은 것인지 정확한 이유는 모르겠다.

디프만 13기 디자인

개발 초기에는 12기때 사용했던 화면에 잡힐 때 애니메이션이 재생되는 방식을 사용했으나 개인적으로 13기 디자인에는 안어울리는 방법이라 판단되었다.


하지만 여전히 인터랙티브한 웹이 되었으면 좋겠다고 생각하여 적용한 것이 배경이 투명한 이미지와 함께 스크롤이 트리거가 되는 애니메이션을 사용하는 것이다.

디프만 13기 인터랙션

개인적으로 많이 고민해서 덜어내고, 적용한 인터랙션이라 기억에 남으며

소프트웨어 설계에서 항상 언급하는 중용과 상황에 따라 다른 것을 디자인에서도 체감할 수 있었던 경험이였다.

커스텀 커서

13기 랜딩 페이지에는 커스텀 커서가 들어가는데,

이 커스텀 커서가 상태에 따라 크기가 변경되어야 하는 요구사항이 있었다.


처음에는 단순히 css를 이용해 cursor: url()과 같이 사용하며, hover 시에 이미지를 바꿔주는 방법을 생각했으나

매끄럽지 않아 사용자 경험이 저하될 것이라 판단되었다.


그렇기에 적용한 방법이 기본 커서를 숨기며

마우스 이벤트에 따라 이동하는 컴포넌트를 두고, 전역 상태로써 커서의 상태를 관리하는 것이다.

커서의 상태가 변할 때 transition을 걸어 자연스럽게 커서의 크기를 변경할 수 있었다.

마우스 이동

마우스 이벤트에 따라 위치를 바꾸는 것을 어떤 방법으로 할지 고민이 되었는데 방법은 크게 2가지이다.

  • requestAnimationFrame을 사용해 불필요한 렌더링을 줄이지만 state를 사용하는 방법
  • state 없이 ref의 인라인 스타일을 변경하지만 moust move 이벤트 마다 렌더링이 발생하는 방법

결과론적으로 후자의 방법을 선택하였다.

가장 큰 이유가 requsetAnimationFrame에서 mouse position을 알 수 있는 방법이 없기에, state를 사용해야 했고 이는 동일하게 mouse move 이벤트마다 state의 변경 요청이 들어간다는 것이다.

throttle을 사용할 수도 있었겠지만, 매 프레임이 갱신되기 이전에 throttle이 돌아갈지 확신하지 못했다.

후자의 방법은 state의 변경 요청 없이 mouse move 이벤트마다 스타일을 바꿔주어 성능상 이점이 있을 것이라 판단했다.

무수히 많은 state 변경 요청보다 무수히 많은 리페인트가 성능상 이점이 있을 것이라 판단한 것이다.


물론 정확하게 확인할 방법이 떠오르지 않기에 확인을 못하여 내 판단이 옳은지 지금도 알지 못한다.

커서의 상태

커서의 상태를 다루기 위해 전역 상태가 필요하다고 생각되었고 context api를 적용할 시 clickable(구독하고 있는)한 요소가 많아 불필요한 렌더링이 발생할 것이라 생각되었다.

이를 해소하기 위한 도구로 recoil, zustand, jotai를 고민하였는데 결과부터 말하자면 도입하게 된 것은 jotai이다.

jotai 도입 과정

이미 글이 길어져 피로감을 느끼실 수 있기에 jotai 도입 과정은 이미지와 PR 주소를 남긴다.


사실 돌이켜 생각해보면 개발이 편하다는 이유로 도입한 것은 아닐까 의심된다.

랜딩 페이지로써 성능을 저하할 요소가 거의 없고, context api를 사용해 실제로 불필요한 렌더링이 발생하는지 확인을 하지 않았기 때문이다.


처음 맞닥뜨린 성격의 요구사항이라 확실하지 않은 추측들로 구현되었다.

그렇기에 제일 기억에 남는 경험임과 동시에 가장 공유하고 피드백을 듣고 싶은 경험이다.

마치며

이 개발기를 통해 가장 전달하고 싶은 점은 엄청나고 숨겨진 개발 방법은 없다는 것이다.


동아리에 들어가서 직장인과 프로젝트하기 이전, 랜딩 페이지를 만들기 이전에는 많은 사람들이 사용하는 서비스는 숨겨진 엄청난 기술이 있을 것이라 생각했다.

나처럼 생각해 많은 사람들이 흔히 말하는 현업인은 엄청난 실력자들이라 생각하곤 한다.

하지만 모두 닿을 수 있을 정도의 거리에 있는 기술과 방법들을 사용하며 현업인이라고 모두가 엄청난 실력자는 아니라는 것이다.

더욱 닿을 수 있는 거리를 늘리기 위해 항상 내가 모르는 방법과 기술을 찾고 내가 아는 것과 비교하는 것이 중요하다고 감히 조언하고 싶다.

물론 내가 FANNG 수준의 서비스를 본 적은 없음은 물론, 오픈소스 프로젝트만 본 것이라 단편적인 경향이 농후한 말인 것을 알아주길 바란다.

마지막으로 많은 사람이 접하고 참여하길 원하는 동아리의 랜딩 페이지를 만듬으로써 내가 만든 것을 다른 사람이 클론 코딩을 하는 경험도 겪을 수 있었는데, 여러 방면으로 감회가 새롭고 따뜻한 경험이였다.


이외에도 다양한 경험을 할 수 있게 만들어준 동아리에 속할 수 있음에 감사하고 동아리에 참여하는 많은 사람들이 나와 같이 긍정적인 경험으로 남길 바라는 마음이 크다.

글에서 다룬 디프만 랜딩 페이지는 www.depromeet.com에서 확인할 수 있다. (아마 23년 9월까지는 본인이 만든 것이 사용될 것이다.)

Footnotes

  1. click-through rate의 약자로, 클릭으로 이루어진 노출수의 비율이다.

hyesungoh

Personal blog by hyesungoh.

I like to share my knowledge for those who wandering in issue.