우리는 이렇게 일한당👩🏻‍💻 : 카카오맵 버그 10분만에 해결하기, Mixpanel 지표 기반으로 프로덕트 개선하기

이은지·2023년 8월 27일
2
post-thumbnail

프론트엔드 주니어의 회사생활 정기 간행물 🌝

🗺️ 카카오맵 버그 해결

S30(Sprint 30)의 QA날... 프로필 페이지 개선 과정에서 카카오맵의 확대/축소/드래그를 막았더니 해당 영역에서 스크롤이 되지 않는 버그 🐞가 발견됐다.

스크롤이 앙대!

🥝: "터치 이벤트를 막아둔 것 같다. 웹에서 마우스휠은 동작하는데 모바일에서만 안되니까." CTO님한테 요정도 인풋을 받고 혼자 코드를 뜯어보기 시작했다.

· 기존 코드

우리는 react-kakao-maps-sdk의 Map 컴포넌트를 사용하고 있었는데, 이 컴포넌트는 다음과 같은 props를 주입 받고 있었다.

export declare type MapProps = {
    draggable?: boolean;
    zoomable?: boolean;
    scrollwheel?: boolean;
    disableDoubleClick?: boolean;
    disableDoubleClickZoom?: boolean;
    onZoomStart?: (target: kakao.maps.Map) => void;
    onZoomChanged?: (target: kakao.maps.Map) => void;
    onBoundsChanged?: (target: kakao.maps.Map) => void;
    onClick?: (target: kakao.maps.Map, mouseEvent: kakao.maps.event.MouseEvent) => void;
    onDoubleClick?: (target: kakao.maps.Map, mouseEvent: kakao.maps.event.MouseEvent) => void;
    onRightClick?: (target: kakao.maps.Map, mouseEvent: kakao.maps.event.MouseEvent) => void;
    onMouseMove?: (target: kakao.maps.Map, mouseEvent: kakao.maps.event.MouseEvent) => void;
    onDragStart?: (target: kakao.maps.Map, mouseEvent: kakao.maps.event.MouseEvent) => void;
    onDrag?: (target: kakao.maps.Map, mouseEvent: kakao.maps.event.MouseEvent) => void;
    onDragEnd?: (target: kakao.maps.Map, mouseEvent: kakao.maps.event.MouseEvent) => void;
    children?: React.ReactNode | undefined;
  	// 다수 생략
};

props 항목들과 각 props의 설명을 보니 🥝님의 말이 맞다는 판단이 섰다. zoom, drag, doubleClick 등의 이벤트에 커스텀 핸들러를 달 수 있게끔 되어 있는거 보니 draggable, zoomable이라는 props를 false로 설정하는 건 그 이벤트들을 무시하게끔 설정하는 것과 같겠지

지도 영역의 스크롤은 가능하되 지도가 움직이지 않게 고정하기 위해서는, 지도 영역에 일어나는 터치 이벤트를 유저의 의도에 따라 두 가지로 구분해야 했다. 지도를 움직이기 위한 터치라면 무시해야 했고, 스크롤을 위한 터치라면 이벤트를 처리(handle)해줘야 했다.

· Map대신 StaticMap을 써볼까

하지만 유저의 스크롤 의도를 코드 상에서 구분할 수 있나? 어렵겠다 싶었다. 그래서 카카오맵 sdk를 둘러보다가 StaticMap 컴포넌트를 발견했다.

애초에 정적 이미지 지도인거니까, 터치 이벤트를 막지 않고도 지도가 고정되어 있도록 구현되어 있겠다 싶었다.

하지만 StaticMap은... 커스텀 마커를 지원하지 않았다.

버그를 고치기 위해선

  • 커스텀 마커를 쓸 수 있으면서
  • 터치 이벤트로 지도를 움직일 수는 없어야 하고(zoomable, 어쩌구 옵션을 써야 하고)
  • 터치 이벤트를 통한 스크롤은 일어나야 했다.

😇
안된다고 할까?

· 내가 해냄

그러다 생각해낸 해결책 !
투명한 div로 그 위를 덮으면 어떨까?

바로 적용해봤다. 투명한 div 엘리먼트에 position: absolute를 설정하고, Map 컴포넌트의 z-index보다 높은 z-index를 설정했더니 내 예상대로 스크롤이 작동했다.


신나서 CTO님한테 말씀 드렸다 하지만 그의 반응은 챠가웠는데...

🥝: CTO님 🐰: 나

🥝 : "근데 이해가 안된다. 자바스크립트 이벤트 버블링은 더 아래에 있는 요소들로 전달되고, 결국 body까지 전달돼야 스크롤이 될텐데. 이게 어떻게 되는거냐. 투명 div에선 이벤트를 consume할 수 없을테니 이벤트가 Map 컴포넌트에 전달될텐데. Map 컴포넌트에서는 터치 이벤트를 씹으니까, Map 컴포넌트에서 더 아래로 내려가지 못하고 막혀야 하는 거 아닌가? "

🐰 : "어 그렇네요. 근데 position:absolute니까. 이건 원래 있었던 위치에서 벗어나게끔 하는거니까 이벤트 버블링이 바로 아래 요소가 아니라 body로 바로 전달된다거나 할 수 있지 않을까요?"

🥝 : "그럴싸한 가설이다 position absolute랑 이벤트 버블링에 대해 한 번 찾아봐라"

🐰 : "옙"

· position: absolute와 이벤트 버블링

chat GPT의 답변

Relation between Position Absolute and Event Bubbling:
Positioning an element as absolute can have implications for event bubbling. When an element is positioned as absolute, it's taken out of the normal flow, and it might not affect the layout of its ancestors. However, this doesn't impact event bubbling directly. Event bubbling occurs based on the DOM hierarchy, not on the layout.
Even if an element is positioned absolutely, its events will still bubble up through the DOM hierarchy as usual. So, if you have nested elements, a click event occurring on an absolutely positioned inner element will still bubble up through its ancestor elements, triggering event listeners along the way.
In summary, "position absolute" and "event bubbling" are distinct concepts. Positioning an element absolutely affects its layout, while event bubbling is a behavior of the event handling model in JavaScript, allowing events to propagate through the DOM hierarchy. The position of an element doesn't impact the bubbling behavior of events.

요약하자면, 이벤트 버블링은 레이아웃이 아닌 DOM 트리를 따라 이뤄진다. 즉 이벤트는 레이아웃적으로 아래에 쌓여 있는 요소가 아닌 돔 트리 상에서 상위에 있는 노드에 전달 된다.

<!-- 프로필 페이지의 대략적인 코드 -->
<body>
	<div>
		<Map />
		<투명div />
	</div>
</body>

Map 컴포넌트와 투명div가 DOM 트리 상으로 동일한 레벨에 있었기 때문에, 투명 div에서 발생한 터치 이벤트가 해당 이벤트를 컨숨하는 (스크롤을 감지하는) 최상위 엘리먼트까지 잘 전달된 것이었다.

이 설명으로 CTO님의 컨펌도 받아내었다~~

이 모든 게... 10분만에 일어난 일
해커톤 같고 빠르고 재미있었다 CTO님이랑 티키타카도 재미있었고 새로운 지식도 배워서 재미있었다

45분 만에 QA 15개 전부 해결하기도 성공!

📈 Mixpanel 기반 프로덕트 개선

이 주제는... 기회가 되면 조금 더 자세히 적는 걸로

Mixpanel 데이터를 수집한지는 좀 됐는데, 이번 스프린트에 처음으로 그 데이터들을 활용해봤다. 데이터 기반 의사결정? 그런거? 나도 해봄 🌝

Mixpanel은 항상 쳐다보기 껄끄러운 마음의 짐 같은 느낌이었는데, 이번 기회에 많이 친해진 것 같아 기분이 좋다

S30 회고에서 celebrate 당했따 안녕하세요 갓또디입니다

이번주도 재밌었다!

🌞 틈새 홍보

밀도 있는 성장을 원하는 주니어 개발자이신가요? 저희 크래쉬컴퍼니에 지원해보세요 🥳 아래 링크들을 확인해보세요. 티타임도 환영입니다~!

0개의 댓글