[Deview 2020] 묻고 한벌로 가!

바나나·2021년 10월 16일
0

deview-2020

목록 보기
1/1

발표명: 묻고 한벌로 가! (네이버 플레이스 한 벌의 코드로 모바일 웹/모바일 앱/PC 웹 서비스 확장 개발기)

링크: https://deview.kr/2020/sessions/378

발표자: 윤영제 - 네이버 플레이스

요약

네이버 플레이스 서비스는 각 업종별로 커스터마이징된 템플릿을 가지고 정보를 제공해주고 있으며, 모바일 기준 통합 검색의 15% 를 담당하고 있다. 이 정보는 지도앱과 제공되는 부분이 겹치고 있어 통합이 필요한 상황이었다.
지도는 모바일앱, PC/모바일웹 서비스를 제공중이기 때문에 이에 따라 각 플랫폼 별 요구사항에 맞춰 서비스를 제공해 주어야 한다.
최대한 중복 코드를 줄이고 도메인별 운영 포인트를 줄이기 위해 했던 고민들에 대한 공유이다.

이슈

  • 플레이스, 지도의 검색 결과가 동일하지 않은 이슈가 있음 -> 통합 필요
  • 각 지도 서비스 플랫폼별로 노출 템플릿에 요구사항이 있음
    • ex. 길찾기 버튼의 유무, 뒤로가기 버튼의 유무 등

모바일 앱 통합

요구사항

  • 웹뷰로 제공해야 하며, 네이티브 <-> 플레이스 웹뷰간 데이터 통신이 필요하다
  • 유저가 어색함을 느끼지 않을 정도의 퍼포먼스를 가져가야 한다

웹뷰의 적용 범위

장소 검색 결과 및 지도 내 마커 클릭 후 디테일 페이지는 플레이스가 가져간다

플레이스 내 서비스에서 지도 웹뷰 표기될 부분 분할

  1. 플레이스는 지도화면 + 업종정보로 나뉘어져있음
  2. 업종정보 부분 컨테이너만 떼어냄
  3. 지도웹뷰에서 해당 부분 노출
  4. 코드상 분기로 웹/지도앱 관련 특화 기능 버튼 노출

유저 검색 플로우

  1. 유저 검색 요청
  2. 지도앱에서 WebView URL 호출
  3. 플레이스 웹서버에서 SSR 결과 전송
  4. WebView 에 HTML load
  5. HTML load 완료 후 지도앱쪽에 메시지 전달
  6. 지도앱은 메시지를 전달받아서 필요한 작업(ex. 지도에 마커표시) 수행

WebView to Native

목적: 플레이스에서 노출된 결과를 지도 마커로 표기

aOS 앱스킴(inapp://)

주소 변경되는 경우 웹뷰에 영향을 주는 사이드이펙트가 있었음.
-> 보이지않는 iframe 을 만들어서 이 컴포넌트가 앱스킴 호출을 담당하는 것으로 처리하였다고 함

iOS webkit.messageHandler

스크롤할때마다 앱스킴 호출시에는 성능이슈가 발생해서 postMessage 로 통신하는 것으로 처리하였다고 함

Native to WebView

기본적으로는 웹뷰 url 호출

문제 : 호출할때마다 화면이 깜빡임
이유 : url 호출 -> 서버에 재호출 -> 서버가 데이터를 새로내려움 -> 깜-빡
의문 : 굳이 화면 요청할 필요없이 목록만 업데이트 하면 되는데?

해결 : 웹뷰레벨에서 사용할 수 있는 글로벌 함수를 플레이스쪽에서 만들어서, 신규 url 호출이 아니라 글로벌 함수 호출로 CSR 유도(로드된 페이지를 SPA식으로 재활용)

WebView, Native event handle

상황 : 앱 레이어가 지도레이어 위에 웹뷰가 깔리고, 웹뷰는 위 일정 height 가 투명이라 지도가 보이는 상태
문제 : 상단 레이어가 웹뷰라서 지도까지 터치이벤트가 안감
해결 : 웹뷰레이어 위에 투명 네이티브 레이어를 깔음 -> 앱이 먼저 터치이벤트 가져감

웹 통합

요구사항

  • 지도 웹은 앵귤러이다
  • 플레이스는 리액트이다
  • 지도 웹안에 플레이스를 넣고싶다 -> iframe 활용

iframe 의 장단점

장점

  • 영역이 완전히 분리/고립 됨 -> 크로스 프레임워크 조합으로도 서로에게 영향을 주지 않음

단점

  • 보안 문제
  • iframe url 은 바로 안보임
  • 디버깅 어려움

유저 검색 플로우 (like app)

  1. 사용자가 검색
  2. iframe url 변경(로드)
  3. 플레이스 서버가 SSR
  4. iframe 의 HTML load
  5. iframe 에서 postMessage({action, data})
  6. 지도웹은 필요한 작업을 진행

통신방법 정의

여러가지 방법이 생기면 나중에 유지보수가 어려워지기 때문에 정립필요

  • 지도 => 플레이스 : iframe url 변경으로만 사용
  • 플레이스 => 지도 : postMessage({action, data})

모바일/웹 차이

  • 가로 스크롤 : 좌우버튼 노출여부 등
  • 세로 스크롤
    - 모바일은 인피니티 스크롤
    - PC 는 페이지네이션
  • PC 의 마우스이벤트 처리 (mouseenter, mouseleave)
  • PC 의 미지원이벤트 처리 (touchevent 로 발생하는 tooltip -> scroll 이벤트로 처리)
  • 사소한 몇가지 컴포넌트의 분기
  • 로그인이 필요한 경우
    - iframe 이 부모창에 로그인 요청 -> 부모창에서 로그인시도 -> iframe 새로고침으로 로그인 쿠키반영

IE 11 폴리필 리서치

  • polyfill.io(채택) : 필요한 폴리필들 가져와서 적용
  • polyfill-library : 필요한 폴리필을 동적 판단. (대규모서비스에서의 퍼포먼스 고려하여 미채택)
  • react-app-polyfill : 미지원 ES2016+ 문법 있음 (찾아내면서 개발하기 번거로워 미채택)

성능개선 포인트

이미지 사이징

  • 노출사이즈에 맞게 썸네일 생성
  • 썸네일의 퀄리티는 내리고 sharpen 값을 올리면 비슷한 품질에 용량을 크게 줄일 수 있음

초기로드 사이즈

  • react-lazyload 로 렌더 퍼포먼스 최적화
  • dynamic loading 으로 초기로드 에셋사이즈 줄임

로드 속도

  • 유니버설 SSR 방식을 가졌는데 초기속도가 느린 이유의 리서치
  • 현 상황에서 웹뷰 노출여부를 지도앱이 판단하는데, 이 지도앱은 웹뷰의 로드완료 메시지를 받아서 처리
  • 메시지 송신 타이밍이 SSR + CSR => useEffect 라서 의미있는 첫 노출이 가능해도 웹뷰미노출
  • SSR load 하자마자 지도앱에 메시지 전달하는 것으로 처리
  • 사이드이펙트로 CSR 완료 전까지 유저인터렉션 불가능하나 사람이 인식하기 어려운 정도의 타이밍

기타

  • 리액트 렌더링 최적화 : props 수정 필요한 부분에 커스텀훅으로 전달해서 불필요한 렌더 줄임
  • 스크롤 최적화 : 전통적인 방식(onScroll + rect calc) => IntersectionObserver 사용

느낀점

개인적으로 앱-웹간 커플링이 심한 프로젝트의 투입이 예정되어있었는데, 우연히 좋은 영상을 보게되어서 이렇게 글을 쓰게 되었다.
플레이스에서 사용하는 스택은 사실상 내가(우리팀이) 선호하고 사용중인 스택과 거의 동일하다. 그래서 플레이스는 개인적으로도 좋아하는 곳이고 나중에 꼭 한번 가보고싶은 곳이기도 하다. 내가 원하는 개발환경과 비슷하기 때문이다.

실무에서 할 수 있는 트러블슈팅류의 내용을 이해하기 쉬운 정도로 잘라서, 많은 부분들을 보여준 좋은 영상이었다. 그리고 수많은 분기와 요구사항 변경으로 고통받았을 것이 느껴진다...

어디서 듣기로도 플레이스의 서비스가 굉장히 빡시다고 들었는데 영상에서 본 요구사항만 봐도 느껴진다..

profile
프론트엔드 개발자입니다

0개의 댓글