HANSPOON 프로젝트 리뷰

나는 이걸 왜 하는가?

  • 못생기고 불편한 spoonacular 웹사이트를 참을 수 없어서
  • 리액트로 제대로 된 웹사이트를 한 번 만들어보고 싶어서

기획의도

  • 코시국에 집에서 요리하는 취미가 늘어날 것이므로, 레시피 사이트를 예쁘게 만들어보자.
  • 레시피 사이트인만큼 검색과 저장에 특화시키고, 많은 정보를 보기 좋게 제공하자.
  • 요새 누가 컴퓨터 쓰냐! 게다가 요리하는 중에는 휴대폰으로만 할 테니 모바일에 편리하도록 만들자.

spoonacular 사이트의 문제점 분석

사이트가 못생겨서 맛없어 보이는 음식들

  • 화이트 바탕에 상세 레시피 창(dialog)은 어둡게 해서 음식 색이 돋보이게.
  • 얇고 깔끔한 폰트로 가독성이 좋게.
  • 주황과 초록 등 포인트 컬러로 상큼하게.

레시피 제공 사이트는 검색이 주요 기능일텐데 검색기능이 숨겨져있음

  • 검색입력창을 헤더에서 제공.
  • 헤더는 어느 페이지에서든, 어느 스크롤 위치에서든 쉽게 접근가능.

모바일로 접근 시 레이아웃이 무너지며 과도한 정보 제공(스크롤압박)

  • mobile first로 UX/UI를 만들기.
  • 스크롤 방향과 위치에 따라 헤더 및 scroll to top 버튼 제공.
  • 과도한 상세정보는 아코디언 UI로 유저에게 선택권 제공.

프로젝트 결과물

삽질의 과정

바다 건너 오는 이미지들

  • 중간 발표 때 이미지 최적화에 대한 질문을 받았기도 하고, 레시피 사이트의 핵심이라 할 수 있는 음식 사진 로드하는 데에 꽤 시간이 걸려 온갖 방법을 다 시도해보았다.
    • spoonacular API에서 제공하는 데이터는 이미지경로를 나타내는 문자열. 이 문자열을 img 태그를 통해 static server에서 다시 받아오는 형태로 렌더링 하는데 이게 오래걸렸다.
    • 이미지가 늦게 뜨는 이유: on-premise 서버인 경우 해외이기 때문에 물리적 거리가 있을 수 있으며 클라우드를 쓴다 해도 region을 Asia 쪽으로 설정해두지 않았으면 멀어서 오래걸리는 것이다.
  • spoonacular API 자체에서 이미지의 크기를 지정해서 받아오게 하는 옵션이 있을 수 있으니 체크해 볼 것 → 이미지 static server에서 사이즈와 타입을 지정할 수 있다는 점을 발견하여 설정했다!
  • react image resize를 통해서 클라이언트 단에서 resize 후 렌더링하는 방법도 있는데, 그런 경우 로딩 속도가 길어질 수 있어서 추천하는 방법은 아님.
  • (보너스로 알게 된 내용) 같은 이미지 파일을 한 html 안에서 여러 개의 img태그로 불러오더라도 모던 브라우저에서는 한 번만 로드되는 최적화처리가 되어있다.
    • 심지어 html 파일에서 link된 css 파일 속 background-image 속성에서 url 함수로 이미지를 가져오는 경우에도 이미 html의 img 태그에서 가져온 경우 새로 로드되지 않고 한 번만 로드한다.

접근성과 사용성 개선

  • 기존 spoonacular 사이트에서는 로그인을 위한 모달창(dialog)이 열렸을 때 뒷배경 스크롤도 씽씽 돌아가고 키보드 네비게이션도 모달 밖 요소들을 다 돌아 사용성이 좋지 않았다.
  • 모달창은 보통 absolute나 fixed이기 때문에 top값을 줘서 위치를 설정하는데, 이 때문에 바탕은 viewport의 최상단으로 돌아가게 된다.
    • 그러면 모달창을 닫았을 때 맨 위로 스크롤이 올라가있기 때문에 모달창 여는 순간의 스크롤 위치를 기억해주었다가 모달창 닫을 때 scrollTo로 제자리로 돌려주어야만 한다.
    • 이 때문에 useRef를 써서 모달창 열 때의 scroll 위치를 기억하는 등 번거로운 작업을 했다. 게다가 이렇게 하니까 모달창을 닫을 때 제자리로 돌아가면서 스크롤이 잠깐 생겼다가 사라지는 문제가 생겼다.
  • 늘 정답을 알고 계시는 야무님의 조언대로 scrollTo로 스크롤을 인위적으로 조작하기보다는 overflow-y를 통해 현재 위치에서 넘치는 부분을 아예 보여주지 않도록 하여 깔끔하게 해결했다.

class component로만 만들 수 있는 Error Boundary

  • ErrorBoundary의 fallback으로 렌더링되는 에러페이지를 만들었다. (뿌듯)
  • 에러 페이지에서 벗어나 메인페이지로 돌아가는 링크버튼을 제공했는데, hasError의 값을 false로 변경할 방법이 없어서 영원히 에러페이지에 갇히게 되었다.
  • url이 바뀌면 hasError을 false로 바꿔주고 싶은데 url을 감지하는 useLocation과 같은 훅은 Error Boundary가 클래스 컴포넌트라 못 쓴다.
  • useLocation으로 location 정보를 받아 prop으로 내려주는 HOC(고차컴포넌트)를 만들어 감싸주었다. 드디어 고차컴포넌트가 기존의 컴포넌트를 받아 향상된 컴포넌트를 만든다는 말이 뭔지 이해했다.

좋았던 점

  • 예외처리(no-image fallback 제공, error 페이지, page-not-found 등)와 사용성을 위한 작업(loading spinner, skeleton UI, validation 후 에러메시지 등)에 꼼꼼히 신경썼던 터라 애착이 더 간다.
  • 무엇보다 깃을 통해 소통하고 프로젝트를 잘 진행해서 매우 뿌듯하고, 지난 프로젝트들은 다음 수업과 일정들 때문에 만들어놓고 방치해두었는데 이번에는 다행히 배포 후 여러 확장된 기능을 추가하는 것에 팀원들의 의견이 모여서 기쁘다.