- Published on
IA SNAP(이아스냅) 기획/디자인/개발/배포 후기

목차
링크
기획
아이폰 스냅 업체 이아스냅을 운영하는 지인의 부탁으로 홈페이지를 만들게 됐습니다. 1차 기획은 기존의 이아스냅 블로그에서 홍보에 사용 중이던 업체, 작가, 상품 소개를 비롯해 샘플 사진을 찾아 보기 쉽게 구성하는 식이었습니다. 하지만 1차 기획 후 디자인, 개발까지 어느 정도 마친 상태에서 블로그로는 커스텀하게 구성하기 어려운 포트폴리오 사진 전시, 탐색 기능을 홈페이지에서 구현하는 방향으로 기획을 변경하게 됐습니다. 기존 것을 갈아엎는 수준의 대대적인 변화였지만 결국 2차 기획대로 다시 만들게 됐죠. 토이 프로젝트 외의 작업은 처음이었지만 클라이언트와 지속적으로 소통하며 요구사항과 피드백을 반영, 조율하는 경험을 할 수 있었습니다.


요구사항
기능
|
사용성
|
디자인
|
성능
|
기능명세서
Gallery - 메인 | |
텍스트 검색창 | 지역, 스튜디오, 예식장 이름을 검색어로 입력받아 이미지를 필터링한다. |
전체/리허설/본식 셀렉트 | 셀렉트 옵션에 따라 이미지를 필터링한다. |
전체/스튜디오 스냅/가봉 스냅/밝은 홀/어두운 홀 버튼 | 버튼에 해당하는 분류에 따라 이미지를 필터링한다. |
이미지 필터링 결과 숫자 | 사용자가 탐색할 정보량을 미리 알 수 있도록 필터링된 이미지 결과 수를 상단에 표시한다. |
이미지 | 리허설/본식 여부, 지역, 스튜디오, 예식장 이름과 함께 그리드 형식으로 표시한다. |
Before & After - 보정 전후 사진 비교 | |
보정 전후 사진 비교 슬라이드 | 중앙의 슬라이드 바를 왼쪽, 오른쪽으로 이동하며 보정 전후 사진을 비교 가능하게 한다. |
파트너 - 제휴 업체 소개 | |
제휴 업체 소개 텍스트, 이미지 | 제휴 업체 SNS 링크, 할인 혜택 내용을 이미지와 표시한다. |
디자인

앞서 기술한 대로 프로젝트가 2차 기획으로 변경되면서 아쉽지만 디자인도 그에 맞게 수정해야 했습니다. 1차 기획대로 개발을 어느 정도 진행한 시점에서 시간이 지체된 상황이었기 때문에 UI는 1차 디자인처럼 Figma로 하는 대신 오픈소스 협업 툴인 tldraw로 간단히 그려 시간을 줄일 수 있었습니다.

아키텍처

VS Code 플러그인인 NEXT.NAV를 이용해 Next.js 프로젝트의 구조를 그래프로 간단히 나타내면 위와 같습니다. app 폴더 메인 페이지의 로직은 Supabase DB에서 데이터를 페칭하는 getImages 함수를 app/page.tsx에서 호출하며 시작됩니다. 호출하여 받아온 데이터를 클라이언트 컴포넌트인 Gallery에 프로퍼티로 전달하면 상태 값에 담아 Search, Select, Themes 컴포넌트에서 발생하는 이벤트에 따라 필터링하여 Images로 렌더링합니다.
스택
YARN vs PNPM
'일을 하기 위한 일'에 드는 시간을 줄이려면 목수가 허리춤에 차는 든든한 연장과 같은 툴을 잘 활용하는 것도 중요한 것 같습니다. 패키지 매니저가 그런 툴 중 하나이니 환경 세팅, 라이브러리 설치 시간을 줄일 수 있는 선택지를 늘리고자 PNPM을 써보기로 했습니다. NPM 사용 중 YARN을 만났을 때 느꼈던 속이 뻥 뚫리는 시원함을 PNPM을 만나며 다시 한번 느꼈습니다. 수치로 알려진 것처럼 체감 속도 또한 굉장히 빨랐습니다. 물론 NPM에서 생성된 lock 파일을 지원하지 않는 등 호환성 관련 문제점이 생길 수도 있다지만 소규모 신규 프로젝트에서는 그 문제점을 상쇄할 정도로 속도가 주는 매력이 컸습니다.
Next.js 12에서 Next.js 13으로
1차 기획을 Next.js 12 버전으로 구현 중인 상태에서 2차 기획으로 바뀌었을 때는 Next.js 13 버전을 프로덕트로 배포해도 안정적이라고 보는 시각이 늘어나던 시점이었습니다. 프로젝트를 처음부터 다시 시작해야 하는 상황이고 page 폴더 기반 12 버전도 언젠가 레거시가 되어 13 버전으로 이전하게 될 거라면 차라리 애초에 13 버전으로 만드는 게 낫다고 판단했습니다. 13 버전에서 바뀐 사항을 익히는 러닝 커브가 시간 대비 낮진 않았지만 마침 Next.js 공식 문서 한국어 번역에 기여하게 되면서 학습 효과가 배가 되기도 했습니다.
Supabase
이아스냅은 이미 블로그, 인스타그램 등으로 홍보 중인 상태에서 홈페이지는 부가적인 용도로 운영될 계획이었기에 서버 관리비 예산을 최소화하는 게 목표였습니다. 예산에 맞는 스택을 찾던 중 Supabase라는 DB를 발견했고 스토리지 1GB, 데이터베이스 500MB, 대역폭 5GB까지 무료 플랜 안에서 사용할 수 있어서 간단한 웹사이트 맞춤용으로 제격이었습니다. 또 클라우드에서 호스팅을 해서 관리, 구축 걱정 없이 쓸 수 있었고 RESTful API를 자동 생성해주기에 데이터를 간단히 조회할 수 있다는 장점이 있어 선택하게 됐습니다.
Vercel
Vercel을 서버로 선택한 것도 비용이 가장 큰 이유였습니다. 대역폭 100GB까지 무료 사용, Git으로 배포 시 CI/CD를 자동화하며 서버리스 함수, 웹 분석, 커뮤니티 지원 등이 가능하다는 장점이 있어 Vercel을 처음 사용하게 됐습니다. 이아스냅의 경우 GitHub 저장소와 연결했고 풀 리퀘스트, 머지 리퀘스트를 통해 간단하게 배포할 수 있었습니다.
Framer Motion
1차 개발 당시엔 GSAP을 이용해 페이지 전체에 Smooth Scrolling을 구현했지만 사용자의 UX에 좋지 않을 수 있다는 글을 우연히 발견했습니다. 스크롤 속도를 늦춰 화면이 부드럽게 넘어가는 효과가 디자인면에서 매력적이라 생각해 선택했지만 사용자의 예상 동작을 벗어나 스크롤 사용을 제한하는 스크롤 납치(Scroll hijacking) 행위로 보는 시각도 있었던 겁니다. 1차 개발의 경우엔 업체와 메뉴를 소개하는 랜딩 페이지였기 때문에 부드럽고 직관적인 탐색에 Smooth Scrolling이 적당했지만 2차 개발에선 메인 페이지가 이미지 갤러리였기에 역효과일 수 있다는 판단에 Framer Motion을 이용해 GSAP보다 가볍고 선언적 구문으로 간단하게 애니메이션을 적용할 수 있었습니다.
문제 해결
폰트 최적화
문제
폰트를 최적화하기 전엔 Network 패널의 throttle 설정을 'Fast 3G'로 선택 후 메인 페이지를 새로고침 하면 위 영상처럼 폰트가 바뀌면서 깜박이며 요소가 밀리는 사용성 문제가 있었습니다.
해결
- 폰트 포맷 변경으로 파일 크기 줄여 다운로드 속도 늘리기
로컬 폰트 파일 크기가 모두 합쳐 1000kB가 넘고 로드 시간이 13초나 걸리는 문제의 원인을 해결하기 위해 파일 크기를 줄여 다운로드 시간을 단축하기로 했습니다. 폰트 포맷 중 파일 크기가 OTF보다 작은 WOFF, WOFF2로 변환 후 브라우저 호환성을 고려해 src 속성에 함께 나열했습니다.
@font-face {
font-family: 'GmarketSansMedium';
src: url('./fonts/GmarketSansMedium.woff2') format('woff2'),
url('./fonts/GmarketSansMedium.woff') format('woff'),
url('./fonts/GmarketSansMedium.otf') format('otf');
font-weight: 500;
font-style: normal;
font-display: block;
}
또 메인 페이지에 필요한 폰트만을 로드한 결과 아래 이미지처럼 용량은 1118kB에서 약 398kB, 로드 시간은 약 3초로 줄었습니다.


- Fontfaceobserver 라이브러리로 폰트 다운로드 완료 시점을 알아내 스켈레톤 UI를 대체하기
로컬 폰트 로드가 완료될 때까지 기본 폰트를 보여주는 대신 스켈레톤 UI를 보여주다가 Fontfaceobserver 라이브러리로 폰트 로드 완료 시점을 알아내 UI 요소와 함께 로컬 폰트 텍스트를 렌더링했고 그 결과 자연스러운 전환이 가능했습니다.
useEffect(() => {
const font = new FontFaceObserver("GmarketSansMedium");
font.load(null, 10000).then(function () {
setIsFontLoaded(true);
});
}, []);
return (
{isFontLoaded? <>
<Search
searchKeywords={searchKeywords}
searchInputHandler={searchInputHandler}
searchSubmitHandler={searchSubmitHandler}
/>
<div
className="z-10 w-full text-sm flex flex-row items-center"
>
<Select selectChangeHandler={selectChangeHandler}/>
<Themes data={themes} themesClickHandler={themesClickHandler}/>
</div>
</> : <PlaceholderTop/>}
)
접근성

이아스냅은 홈페이지 제작 전부터 로고와 브랜드 컬러가 이미 베이지, 핑크톤으로 정해진 상태여서 그에 맞춰 배경색과 포인트 컬러도 정했습니다. 하지만 로고 색에 가까운 색으로 폰트 색을 지정했더니 Lighthouse 접근성 항목에서 배경 색-폰트 색 대비율이 WCAG 기준인 4.5:1(작은 글자)에 안 맞다는 경고를 받았죠. 자료를 참고해 대비율이 높은 색으로 바꿔야 했습니다.



브랜드 컬러와 최대한 유사하게 폰트 색을 유지하려던 기획에서 벗어나야 했기에 디자인과 접근성을 두고 고민했지만 사용자 입장에서 디자인보다 접근성이 우선한다는 원칙을 지키기로 하여 메인 폰트 색을 변경한 결과 캐러셀 라이브러리 자체 이슈를 제외하고는 접근성 항목에서 문제가 발견되지 않았습니다.