일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 자바스크립트
- 분기 회고
- 개발공부
- typescript
- React Query
- 개발 공부
- 항해 플러스 프론트엔드
- 개발자
- wil
- 테스트 코드
- 성장일지
- FE
- rust
- React
- 성능최적화
- 항해 플러스
- frontend
- naver
- javascript
- 리뷰
- GPU
- 항해
- 항해플러스
- 프론트엔드
- 알고리즘
- 항해99
- 보안
- webGPU
- 백준
- 회고
- Today
- Total
느릿늘있
[nextJS] Google Map API 성능 최적화 경험 기록 본문
1. 현상
사이드 프로젝트로 진행 중인 머글래 웹 모듈 4번 작업물인 구글 맵 api를 활용한 지도에 리뷰 표시하는 페이지를 만들 던중 발생한 이슈다. 아래 링크에서 현재 잘 동작하고 있는 것을 확인할 수 있다.
https://moglet-web-module.vercel.app/4_googleMaps
처음에는 모든 기능을 index 페이지에 다 몰아 넣고 기능이 동작 가능하게만 만들어서 돌렸다. 그랬더니 노트북 팬이 미친듯이 돌아가고 브라우저는 멈추고 작업관리자 CPU는 100%를 찍고 vercel에 배포는 됬으나 사이트가 먹통이 되어 버렸다. 성능에 문제가 있다는 것을 인지하고 이를 최적화 하기 위해 여러 가지를 시도하였는데 최종적으로 적용된 기능 사항들을 정리해보고자 한다.
2. 원인
내가 생각했을 때, 성능이 미쳐버린 가장 큰 원인은 useState의 무분별한 사용이었다. 나는 google map 컴포넌트 위에다가 marker를 여러개 찍었는데 이 마커를 버튼을 누를 때마다 갱신해야 했다. 한 페이지에서 useState로 모든 데이터를 관리했기 때문에 React는 state가 업데이트 될 때마다 전체 페이지에 대한 re-render 여부를 계산해야 했을 것이다. (관련 내용 링크 참조)
두번째 원인은 서버 데이터 관리를 위해 사용한 ReactQuery의 useInfiniteQuery 사용 과정에서 getNextPageParam 안에 setState를 사용했었기 때문이다. 마지막 페이지에 도달한 경우 버튼의 상태를 변경하는 setter 함수를 이 안에다가 사용했는데 getNextPageParam 내부에 로그를 찍어보면 알겠지만 정말 여러번 호출된다...(정확히 어떤 이유로 이렇게 동작하는 지는 모르겠다.) 첫번째 이유와 연결지어 생각해보면 정말 많은 양의 redering 요청이 발생했을 것이다.
3. 해결
우선은 하나의 컴포넌트에 몰려있던 기능과 UI들을 분리했다. 최상단 index에는 google map을 로드하고 map과 관련된 내용들만 관리하도록 설정했다. 그리고 내부에 있던 marker와 reviewTable(마커 클릭 시 생기는 modal UI)을 따로 분리했다. 기존에는 이들의 정보가 갱신될 때마다 전체 페이지에 대한 계산이 수행됬을 테지만 이들을 하위 컴포넌트로 분리하여 google map에 대한 계산을 최소화하였다. 이에 더하여 useState의 사용을 지양하고 flux 패턴 적용을 위한 Redux-toolkit(RTK)을 적용하여 클라이언트 데이터 관리를 더 쉽고 안전하게 변경하였다.
그리고 getNextPageParam에서는 오직 다음 페이지 offset을 계산하는 로직만 남겨두었고, 데이터의 상태에 따른 추가적인 동작들은 onSuccess 내에서 관리하도록 수정하였다.
'삽질로그' 카테고리의 다른 글
[JS] 배열 탐색 : forEach, filter, find (0) | 2023.11.29 |
---|---|
[개발 환경] WSL2 UNC 경로 에러 (0) | 2023.07.25 |
[SQL] 쿼리문 변경을 통한 성능 향상 경험 (0) | 2023.06.13 |
[JS] 참조 객체 비교 에러 : This condition will always return 'false' since JavaScript compares objects by reference, not value. (0) | 2023.04.02 |
[react query] 응답 status는 success인데 data가 undefined인 경우 (0) | 2023.03.28 |