사이드프로젝트 slecs

브라우저에 북마크·영상 미리보기·페이지 전환 감지 초기화 추가

목차

이번 작업 한 줄 요약

브라우저 컴포넌트 손봤음. 주소창에서 북마크 토글, 영상 썸네일 위에서 짧은 미리보기 재생, 페이지 이동할 때 감지 상태 초기화 — 세 가지가 한 번에 묶였음.

왜 묶어서 했나

세 기능이 별개처럼 보이지만 결국 다 주소창과 페이지 라이프사이클을 건드리는 작업이라 분리해서 PR 따는 게 더 번거로웠음. 의존성도 비슷했고.

기능 트리거 영향 범위
주소창 북마크 별 아이콘 클릭 주소창 UI + 저장소
영상 미리보기 썸네일 hover 미디어 핸들러
감지 초기화 URL 변경 이벤트 페이지 라이프사이클 훅

북마크 토글

별 아이콘 상태가 현재 URL이 저장소에 있는지 여부와 동기화돼야 했음. 처음에는 클릭 핸들러에서 직접 저장소 조회했는데, 그러면 다른 탭에서 저장한 변경이 반영 안 됐음. 결국 URL 변경 이벤트 + 저장소 변경 이벤트 둘 다 구독해서 상태를 끌고 가는 식으로 바꿈.

useEffect(() => {
  const sync = () => setBookmarked(store.has(currentUrl));
  store.on('change', sync);
  sync();
  return () => store.off('change', sync);
}, [currentUrl]);

영상 미리보기 재생

썸네일 hover 시 짧은 클립을 재생하는 건데, 진짜 골치 아팠던 건 hover out 했는데 비디오가 끝까지 로드되는 케이스. 네트워크 요청이 hover 떠난 뒤에도 살아있어서 메모리도 새고 다른 hover와 레이스도 났음.

해결 방법:

  • hover 진입 시 AbortController 발급
  • hover 이탈 시 abort + pause() + src='' 로 디코더 끊기
  • 동일 카드 재진입은 캐시 활용해서 재요청 안 함

package.json에 미리보기용 라이브러리 하나 추가했고, lock 파일 갱신됐음. 의존성 트리에서 중복 패키지가 좀 늘긴 했는데 현재로썬 감수하기로 함.

페이지 이동 시 감지 초기화

이게 제일 미묘했음. 페이지 안에서 떠 있던 각종 감지 상태(스크롤 깊이, 미디어 인덱스, hover 캐시) 가 다음 페이지로 넘어가도 그대로 남아 있었음. 같은 SPA 안에서 라우트만 바뀌면 컴포넌트가 언마운트 안 되니까 자연스럽게 초기화가 안 됐던 것.

  • 라우트 변경 이벤트를 단일 출처로 잡고
  • 거기 구독한 컴포넌트들이 본인 상태를 reset 하도록 통일
  • 컴포넌트마다 따로 useEffect 거는 패턴 치움

이렇게 했더니 "뒤로 가기 후 hover 했는데 이전 페이지 미리보기 뜨는" 버그가 사라짐.

회고 포인트

  • 묶은 PR이라 리뷰가 길어진 건 살짝 아쉬움. 다음엔 라이프사이클 리팩터만 따로 빼는 게 깔끔할 듯함.
  • hover 같은 짧은 인터랙션도 레이스/누수 가능성 늘 의심해야 함을 다시 확인함.
  • "상태 초기화 책임을 누가 갖냐" 가 결국 SPA 구조에서 반복되는 질문이라는 걸 또 느낌.

댓글 0

첫 댓글 달아줘.