💾 나의 첫번째 사이드 프로젝트
작년에 진행하였던 사이드 프로젝트인 Which Beach Search를 마무리하고 스타트업에 입사를 했었다.
지금은 이직을 위한 포트폴리오를 작성중에 있는데 포트폴리오를 작성하다보니 이 프로젝트를 할 때 고민했던 부분과 해결 한 부분 그리고 느낀 점에 대해 정리를 하다보니 생각보다 너무 길어져서 ㅎㅎ... 이 블로그에 적어서 링크하기로 결정했다.
자바스크립트 강의를 배우자마자 시작했던 프로젝트라 많이 미숙하기도 하고, 모든게 다 새로워서 하면서 좀 머리도 쥐어짜고 했지만 어쨌든 기대 이상의 결과물을 얻어서 나름 만족스러운 프로젝트였다.
하지만 마무리하지 못한 부분이 꽤 보여서 현재 조금씩 리팩토링하고있다..
🤦🏻 고민과 해결
1. xml to json 데이터 타입 변환
- 공공기관 API 데이터 중 일부는 xml 타입만 요청 할 수 있었음
- xml 데이터 요청 후 github에서 가장 유명했던 xml2json 라이브러리를 사용하려고 하였으나, 최근 5~6년간 업데이트가 이루어지지 않은 상태였기에 사용하기 우려스러웠음
- ES5 문법이 사용 된 라이브러리로 ES6 사용하는 프로젝트라 적용하기 불편함
- 순수 js로 xml to json 하는 방법을 찾아서 적용하여 json 타입으로 변환하여 해결하였음
이 부분에 대한 자세한 과정은 이 블로그의 다른 글에 작성되어 있음.
2. 화면 간 데이터 전달
- 즐겨찾기 화면과 지도 화면에서 선택한 해변의 상세정보를 누르면 메인 페이지로 이동 함
- 선택한 해변의 해변 코드를 갖고 메인 화면으로 넘어가야 해당 해수욕장 데이터를 로드 함
- 화면 간에 데이터 전달 방법을 고민하게 됨
- 브라우저 저장소 : LocalStorage 또는 SessionStorage 활용
- URL 주소 : Query String 활용
- 브라우저 저장소 이용 시 데이터가 계속 남아있다보니 저장된 데이터를 지워줘야하는 번거로움이 있음
- Query String을 활용하면 간단하게 주소창으로 데이터 전달이 가능
- 보내는 데이터가 해변코드, 위도, 경도 정도의 간단한 데이터라 URL Query String 활용으로 결정
- 데이터 전달 후에는 주소창에서 데이터 부분만 제거
history.replaceState({}, null, location.pathname);
3. API 데이터 처리
- 필요한 데이터를 수집하기 위해 총 3개의 REST API를 요청하는 상황
- 시간 및 3일 날씨 : 전국 해수욕장 날씨 조회서비스
- 4일 ~ 7일 날씨 : 중기예보 조회서비스
- 일출, 일몰 시각 : 한국천문연구원 출몰시각 정보
- 하나의 해수욕장 정보를 표시하기 위해 여러 API 호출이 필요하였음
- 외부 사이트를 이용하여 제공 되는 정보를 위해 각 해수욕장의 링크도 필요
- 크롤링 검토하였으나 일정한 형태의 정보를 갖고 있지 않아서 예외처리 사항이 너무 많음
- 해수욕장 정보 사이트와 API에서 동일한 해수욕장의 이름이 다름
- 해수욕장 날씨 데이터는 3일까지 제공 됨
- 4일부터는 지역 코드와 해수욕장과 인접한 도시 코드를 활용한 중기예보 데이터를 활용해야 함
- 해수욕장의 상세 정보가 제공되는 외부 사이트가 다른 경우가 있음
- 크롤링 프로그램 + 모든 예외처리 분석 등에 소요되는 시간이 많아 구글 스프레드 시트에 직접 필요 데이터를 작성하여 데이터 베이스로 사용하기로 함.
4. 비동기 문제
- 구글 스프레드 시트 API를 활용하여
query.send
요청하여 리턴 받는 값에 대해 json 타입으로 파싱중에 문제가 발생
query.send
반환 값을 json타입으로 파싱 하는 함수의 매개변수로 넘겨서 json 데이터를 사용하려고 했는데 콘솔에는 찍히지만 활용하는 함수 쪽에선 데이터가 없다고 나옴
async function getSpreadSheetsDataList(query) {
query.send(response => {
if (response.isError()) {
console.error(
'Error in query: ' +
response.getMessage() +
' ' +
response.getDetailedMessage(),
);
return;
}
return dataListParsing(response);
});
}
- 이런 저런 방법으로 확인해보니
query.send
결과 값이 json 타입으로 파싱 되기 전에 함수가 종료되고, 뒤늦게 콘솔에 파싱된 json 데이터가 나타나는 것을 확인
query.send
가 비동기이다 보니 json 파싱 함수의 결과를 기다리지 않고 끝나서 문제가 된 것
- 비동기를 동기로 동작하도록 Promise 사용하여 json 파싱 결과를 기다린 후에 함수가 종료되도록 하여 해결
async function getSpreadSheetsDataList(query) {
return new Promise((resolve) => {
query.send(response => {
if (response.isError()) {
console.error(
'Error in query: ' +
response.getMessage() +
' ' +
response.getDetailedMessage(),
);
return;
}
resolve(dataListParsing(response));
});
});
}
5. 데이터 처리 중의 상호작용 방지
- 북마크 등록 시 연달아서 클릭하게 되면 이벤트가 중복되면서 에러가 발생
- 중복된 상호 작용을 방지하기 위해 이벤트가 호출되어 데이터가 처리될 때 스피너 로딩 화면을 띄워서 화면 클릭을 방지
6. 메인 화면 로드 속도
- 메인 화면 로드 속도가 여러 API 요청 때문인지 6~7초 정도 소요 됨
- Light House 프로그램으로 측정해보니 메인 화면에 사용 된 이미지 크기가 커서 영향이 있다고 나옴
- 이미지를 압축(2.8Mb -> 100Kb)로 변환하니 로드 속도가 4~5초로 단축 됨
- 메인 화면 로드될 때 스피너 로딩 화면을 띄워서 사용자가 현재 화면이 로딩 중임을 인지하도록 함
7. 지도 API 활용
- 카카오 지도 API를 선택한 이유?
- 구글 지도나 네이버 지도 API보다 문서가 친절하게 되어있음
- 지도에 모든 해수욕장을 표시해야 했는데 마커와 인포윈도우 기능이 있었음
- 무료 이용에 대한 부분이 1일 30만 건으로 API중에 제일 좋았음
🧐 아쉬운 점
- 메인 화면의 js 파일에 모든 로직이 담겨 있어서 코드의 가독성이 현저히 떨어짐
- 리팩토링을 통해 firebase 서비스, 데이터 처리 로직 등의 함수들을 분리해주어야 함
- 메인 화면 로드 속도 문제
- 이미지 크기를 줄였다해도 여러 API를 요청하다 보니 화면의 로드 속도가 만족스럽지 못함
- API 데이터 요청에 대한 속도 개선 문제에 대한 학습이 필요
- 웹에 맞는 UI의 부재
- 모바일 웹 사이즈 기반으로 제작하였지만 웹에서도 사용할 수 있는 반응형 UI가 없어서 아쉬움
- 지도 화면 검색 창의 자동 완성 기능 미구현
- 메인 화면에는 구현되어 있지만 지도 화면에서는 일정의 문제로 구현되지 못함
💡 배운 점
- Figma를 사용하여 기초 화면 설계
- 서버리스 환경(Firebase)에서의 데이터 관리 및 처리
- Firebase기반 계정 관리 방법
- 회원가입, 로그인 양식 데이터의 검증 및 예외 처리
- 공공기관 REST API, 카카오 지도 API 등과 같은 API를 Axios로 요청하여 활용하는 방법
- 비동기 처리 방법과 에러처리
- async, await, then, catch 등의 기본적인 활용 방법
- 비동기를 동기로 처리하는 방법
- Query String을 이용한 데이터 전달 방법
- Jira, Git flow 등을 이용한 프로젝트 일정 관리 및 일감 정리와 프로젝트 버전 관리