개발 slecs

탤런트 검색은 빠르게, 즐겨찾기는 간단하게

목차

지난주에 탤런트 프로필 서비스의 검색과 즐겨찾기 기능을 손봤다. 클라이언트 사이드에서 검색을 처리하고, 즐겨찾기는 localStorage에 저장하는 방식으로 구현했는데, 이 결정이 꽤 흥미로운 트레이드오프를 포함하고 있었다.

왜 클라이언트 검색인가

탤런트 목록이 수백 개 수준인 우리 서비스에서 검색 기능을 추가할 때 처음부터 고민이 있었다. 서버에서 필터링할지, 클라이언트에서 할지. 팀 내 토론 결과 클라이언트 사이드 검색을 택했는데, 이유는 명확했다.

사용자가 검색어를 입력할 때마다 네트워크 요청을 보내면 지연이 생긴다. "검색" 같은 2글자만 입력해도 API 왕복이 일어나고, 결과가 돌아올 때까지 기다려야 한다. 하지만 클라이언트에서 처리하면 입력하는 순간 즉시 필터링이 된다. 사용자는 '끊김 없는' 경험을 느낀다.

또 다른 관점은 비용이다. 매번 검색할 때마다 데이터베이스 쿼리를 돌릴 필요가 없다. 특히 트래픽이 늘어나면 서버 부하가 누적된다. 클라이언트 필터링이면 그런 걱정이 없다.

물론 트레이드오프가 있다. 탤런트 데이터가 현재의 수백 개에서 수천 개로 커지면 초기 로딩 시간이 늘어날 수 있다. 하지만 지금 단계에서는 더 중요한 건 사용자 경험의 반응성이었다.

즐겨찾기는 localStorage로 충분했다

즐겨찾기 기능을 구현할 때도 선택지가 있었다. 백엔드 데이터베이스에 사용자별로 저장할지, 브라우저의 localStorage에만 둘지.

저장소 즐겨찾기 유지 기기 간 동기화 구현 복잡도 운영 비용
localStorage 해당 기기에서만 미지원 낮음 거의 0
서버 DB 영구 유지 지원 높음 증가

현재 우리 팀 상황과 사용자 니즈를 고려하면 localStorage가 맞다고 판단했다. 왜인가?

첫째, 즐겨찾기는 "가벼운" 기능이다. 사용자가 몇 명의 탤런트를 저장해두는 정도면 충분하다. localStorage 크기 제한(보통 5~10MB)에 갇힐 일이 거의 없다.

둘째, MVP 단계에서 백엔드 인증, 데이터베이스 마이그레이션, API 설계 같은 걸 다 해야 한다면 출시가 밀린다. localStorage면 프론트엔드만 건드리면 된다.

셋째, 초기 사용자들은 "계정 없이도 쓸 수 있는 사이트"를 선호하는 경향이 있다. 즐겨찾기를 위해 로그인을 강요하지 않을 수 있다는 건 큰 장점이다.

구현하며 나눈 고민들

파일 구조를 보면 TalentCard, TalentsBody, FavoritesBody, favorites 페이지가 다 손을 봤다. 이건 한 사람이 혼자 다 할 수도 있는 양이지만, 팀에서 리뷰할 때 각 부분의 책임이 명확한지, 중복 코드가 없는지 체크했다.

특히 TalentCard에서 즐겨찾기 버튼의 상태(저장됨/미저장)를 관리하는 부분이 중요했다. Astro는 기본적으로 정적 사이트 생성기지만, 클라이언트 인터랙션을 위해 client:load directive를 써야 한다. 그러면서도 SSR의 장점을 유지하려고 신경썼다.

다국어 지원(ui.ts 수정)도 빼먹을 수 없었다. 검색 placeholder나 버튼 텍스트가 여러 언어로 제공되려면 모두 i18n 설정에 들어가야 한다. 이건 개발자가 깜빡하기 쉬운 부분이라서 코드리뷰 때 체크리스트로 만들어두었다.

앞으로의 고민

이 구조는 향후 어떻게 확장될까? 만약 나중에 사용자 계정 시스템을 추가하면, 즐겨찾기를 서버로 마이그레이션해야 할 것 같다. localStorage에 있던 데이터를 어떻게 병합할지가 설계 이슈다. 지금부터 그걸 염두에 두고 localStorage 구조를 설계하는 게 현명할 것 같다.

또 한 가지는 성능이다. 탤런트 리스트가 정말 커질 때쯤엔 클라이언트 검색 대신 가상 스크롤링이나 서버 필터링으로 넘어갈 가능성도 있다. 하지만 지금은 이 방식이 팀과 사용자에겐 최적이다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.