
포인핸드 웹 사이트 리뉴얼
운영 중2026.06 ~ 2026.08 · 개인 프로젝트
운영중인 유기동물 입양 사이트 '포인핸드'를 리뉴얼한 개인 프로젝트
왜 만들었나
공백기 이후 3년만에 다시 개발을 시작하였고, 기초의 중요성과 끊임 없는 학습의 중요성을 느꼈습니다. 과거 구글링과 Stack Overflow에 의존하면서 정보를 찾아가면서 개발을 했던 방식에서 벗어나, AI 에이전트를 적극 활용하며 복기하고 디버깅하고 다투기도하고 검증하면서 바닐라JS의 동작원리를 깊이 있게 학습을 하였습니다. 비동기 API통신을 주제로 삼고 뭘 만들어볼까 하다가 유기동물에 대한 관심이 컷었고 유기된 고양이를 입양 했었던 추억도 있어서 리뉴얼을 해보고 싶었습니다.
주요 기능
- 히어로 배너, 지역별 추천동물 필터, 베스트 후기, 유기동물 현황 미니 대시보드
- 실시간 키워드 검색, 상태 필터, 정렬, 더보기 페이지네이션, 찜하기
- 공고번호 기반 상세 조회, 이미지 갤러리, 성격/입양 절차, 댓글
- 보호소 카카오맵 마커(주소→좌표 지오코딩), 조건 필터 모달
- 회원가입/로그인(중복확인·비밀번호 규칙 검증), 체험 계정 로그인
트러블 슈팅
AI 에이전트를 활용한 구현 속도 단축과 코드 분석 및 학습
문제:바닐라 JS로 공공 API를 연동하는 과정에서 막히는 부분이 많았음.
해결 결과:AI(Gemini, Claude)로 빠르게 해결하되, 단순 복사에 그치지 않고 코드 구조와 비동기 처리 방식을 직접 뜯어보며 수정하며 학습함.
배운 점:AI가 준 코드를 그대로 쓰지 않고 구조와 원리를 직접 뜯어봐야 진짜 실력으로 남는다는 걸 배움.
바닐라 JS 하드코딩의 한계
문제:자바스크립트만으로 DOM을 일일이 제어하다 보니 재사용성과 유지보수의 어려움을 체감함.
해결 결과:우선 프로젝트 범위 안에서는 반복되는 DOM 조작 로직을 함수로 묶어 재사용성을 높임.
배운 점:이 경험을 계기로 다음 프로젝트는 React로 컴포넌트 기반 리팩토링을 하겠다는 목표로 이어짐.
반응형(Mobile/Tablet) 레이아웃 꺠짐
문제:브라우저 크기를 줄였을 때(반응형 모드) 고정된 height 값 때문에 세로 높이는 유지된 채 이미지가 세로로 눌리거나 찌그러짐.
해결 결과:고정 높이 대신 aspect-ratio 속성을 추가해서 브라우저 가로 폭이 줄어들더라도 세로 높이가 원본 비율에 맞춰 유연하게 축소되도록 대처.
배운 점:고정 height보다 aspect-ratio 같은 비율 기반 속성이 반응형에 훨씬 안전하다는 걸 배움.
공공API가 응답하지 않는 현상
문제:어제까지 정상적으로 API데이터들이 잘 불러와졌으나 다음날 데이터통신이 에러가 나옴 → Console에는 어떠한 오류도 안뜸 → Network 탭 확인 결과 pending 상태 무한 대기. 1차로 트래픽, 서버, 인증키 문제인 줄 알았지만 아니었음.
해결 결과:API 엔드포인트가 http로 되어있던 걸 https로 수정 후 해결 완료.
배운 점:에러 메시지가 안 뜨는 네트워크 문제는 Network 탭에서 pending 상태부터 확인해야 하고, http/https 프로토콜 불일치 같은 기본적인 것도 놓치기 쉽다는 걸 배움.
공공 API 단건 조회 불가 및 데이터 유실 문제
문제:단건 조회용 API가 따로 제공되지 않아, 목록 조회(List) API만으로는 특정 항목 하나만 불러올 방법이 없었음.
해결 결과:목록 조회 API 호출 시 전체 데이터를 한 번에 불러온 뒤, 전역 상태나 배열 메서드(find)를 활용해 사용자가 클릭한 고유 ID(id 또는 data-id)와 일치하는 데이터를 프론트엔드에서 즉시 필터링하여 단건 조회처럼 작동하도록 우회 로직 구현.
배운 점:외부 공공 API 스펙에 원하는 기능(단건 조회)이 없을 때, 프론트엔드에서 우회 로직으로 보완할 수 있다는 걸 배움.
전체 목록에서 클릭한 항목만 찾아 단건 조회처럼 사용
const selectedAnimal = animalList.find( (animal) => animal.id === clickedId );API 데이터 로딩 속도 및 초기 렌더링 성능 저하 문제
문제:불러오는 데이터가 500건에 달해 초기 로딩 페인팅 속도와 렌더링 성능이 저하됨.
해결 결과:무거운 메인 배너 SVG를 가벼운 PNG 포맷으로 전환하고 적절한 압축을 거쳐 초기 로딩 속도를 단축, 연관성 없는 독립적인 API 호출들을 순차 방식에서 Promise.all을 이용한 병렬 실행 구조로 변경해 전체 응답 대기 시간을 대폭 단축, 이미지 태그에 loading='lazy' 속성을 적용해 뷰포트에 진입할 때만 이미지가 로드되도록 지연 로딩 최적화 구현. 이렇게 어느정도 해결을 했지만 건수도 500건이였어서 200건으로 축소해 최종 해결.
배운 점:성능 최적화는 한 가지 방법이 아니라 이미지 포맷, 병렬 처리, 지연 로딩, 데이터 양 조절을 종합적으로 봐야 효과가 난다는 걸 배움.
순차 호출 → Promise.all 병렬 실행으로 변경
// Before: 순차 실행 (하나 끝나야 다음 호출) const shelters = await fetchShelters(); const animals = await fetchAnimals(); // After: 병렬 실행 (동시에 요청, 제일 느린 것 기준으로만 대기) const [shelters, animals] = await Promise.all([ fetchShelters(), fetchAnimals(), ]);이미지 지연 로딩
<img src={animal.imageUrl} alt={animal.name} loading="lazy" />
느낀 점
바닐라 JS로 실제 서비스 하나를 처음부터 끝까지 완성해보니, 프레임워크 없이도 상태 관리와 캐싱 전략을 신경 써야 한다는 걸 체감했습니다. 특히 백엔드 없이 localStorage/sessionStorage만으로 로그인과 데이터 캐시를 구현하면서, '서버가 있었다면 이렇게 하지 않았을 것'이라는 지점들을 명확히 인지하고 문서화하려고 했습니다. 공공 API의 스펙 한계를 프론트엔드에서 우회하는 경험도 많이 배웠습니다.