내용
현재 피유엠피(‘씽씽’ 킥보드 공유 업체)에서 작업자 앱( 명칭: 마스터 앱 )을 react-native 기반으로 개발하고 있습니다. 마스터 앱은 스쿠터의 수거, 재배치, 수리, 배터리 교체등의 작업을 도와주는 기능들을 갖고 있는 앱입니다. 마스터 앱에서 가장 중요한 부분은 수거, 긴급, 분실 등 8가지 상태로 나눠져 있는 작업 상태의 마크들을 지도에 표시하는 기능입니다. 하지만 새로운 스쿠터가 들어오고 지역이 확장되면서 마크의 종류들과 양이 많아지면서 속도 이슈가 생겼습니다. 그리고 작업자분들 중에는 성능이 좋지 않은 휴대폰으로 작업하시는 분들도 있어서 지도와 마크의 성능이 잘 나오지 않는 문제를 맞닥뜨렸습니다.
지도는 처음에 react-native-maps (구글 지도) 라이브러리를 사용했지만 해당 라이브러리의 성능이 좋지 않았습니다. 라이브러리에 의존해서 성능을 키우는 것보다는 직접 네이버 지도를 모듈화하고 성능을 개선하는게 좋아서 네이버 지도 module을 개발했습니다. 또한 작업자가 작업할때 구글지도의 정보가 실제 위치의 정보와 틀려 네이버 지도가 필요한 상황이기도 했습니다. 모듈화를 진행하고 네이버 지도에서 제공해주는 라이트 모드를 적용시켜서 지도의 퍼포먼스를 높였습니다. 하지만 지도의 퍼포먼스는 좋아졌지만 점점 마크가 많아지면 앱을 사용하면 성능이 나빠지는 현상은 아직도 있었습니다.
안드로이드에서 제공해 주는 프로파일러로 확인한 결과 마크의 메모리 누수가 많다는걸 알고 Hook을 이용해 효율적인 렌더링이 되도록 했습니다. 이전에는 어떤 상황이든 rendering 이 되면 마크를 새로 받아서 보여줬던 코드를 useMemo 통해 값이 변경될 때만 렌더링 되도록 수정했습니다.
이전 코드
let scooterMarkers = _.map( scooters, ( scooter ) => {
return (
<Marker >…</Marker>
)
});
....
<MapView> {scooterMarkers} <MapView/>
이후 코드
const renderCollectMarker = useMemo(() => {
if( mode === COLLECT ) return collectionScooterMarkers
},[ collectionScooterMarkers ])
const renderBatteryMarker = useMemo(()=> {
if( mode === BATTERYLOW ) return batteryScooterMarkers
},[ batteryScooterMarkers ])
useMemo를 통해서 메모리 누수는 어느정도 해결했지만 스쿠터 양과 서비스 지역이 늘어나면서 가져오는 양 때문에 느린 문제는 아직 있었습니다. 그래서 앱 화면에 보이는 부분만 스쿠터를 가져오는 방법을 생각해서 개발했습니다. 처음에는 디바이스 양 상하단 끝점의 실제 좌표를 가져와서 해당 폴리곤에 있는 스쿠터를 보여주는 방식을 선택했지만, 작업자가 지도를 돌리면서 작업한다는 것을 알고 다시 화면의 사각형의 모든 좌표를 이용하는 방식으로 변경했습니다.
모든 문제가 해결된줄 알았지만 카프카에서 마크를 호출하는 api를 과도하게 쏘는 이슈가 있었습니다. 그래서 확인해 보니까 지도를 조금만 이동해도 해당 api를 호출하는 경우가 많았습니다. 그래서 카메라의 움직임과 api를 통제하기 위한 개발이 필요했습니다. 네이버 지도 sdk에서 안드로이드는 OnCameraIdleListener를 통해서 사용자의 움직임이 멈추는 이유를 파악해 손가락이 때지면 api를 호출할수 있도록 개발했고, ios mapViewCameraIdle:를 delegate형식으로 개발을 했지만, 안드로이드와는 다르게 사용자의 손가락이 지도에 붙어 있어도 화면 이동이라고 인식하고 api를 쏘는 문제가 있어 추가 개발이 필요했습니다.
그래서 앱 화면의 중심 좌표와 이후에 지도 이동후의 중심 좌표 사이의 거리가 1.5km 이상일때만 api를 호출하도록 개발했습니다. 그리고 중복 event 호출 자체를 줄이기 위해서 throttle 을 통해서 중복해서 들어오는 요청을 막아 호출양을 줄였습니다.
지도와 마크의 성능을 많이 개선했고 사용자의 만족도가 좋았습니다. 하지만 계속 킥보드와 지역이 늘어나고 마크에 생기는 기능들이 추가 되면 더 좋은 방법들을 고려해야 한다고 생각합니다. 미리 데이터를 받아서 캐싱 한 후 마크를 보여주는 방법, java, objective-c 모듈에 효율적인 코드를 통해서 메모리 관리, 서버차원에서 가져오는 데이터 속도를 높이는 방법등 더 좋은 방법이 없는지 찾고 있습니다.
'개발이야기' 카테고리의 다른 글
그로잉 서비스 개발 이야기-2 (0) | 2023.03.21 |
---|---|
그로잉 서비스 개발 이야기-1 (0) | 2023.03.21 |
Ble 자동 점검 개발 스토리 (0) | 2022.03.30 |
JWT 인증방식 (0) | 2022.03.29 |
프런트 지식 (0) | 2021.07.29 |
댓글