[비정기적 기록] WebView 프로젝트를 마무리 지으면서

SANGHYUN KIM·2024년 9월 3일
0

비정기적 기록

목록 보기
5/6

늦었지만 백오프피스만 하다가 첫 유저화면(Webview)를 혼자서 처음부터 끝까지 하면서 겪은 것을 적는다.

요구사항 및 기술선정

프로젝트는 타사 어플리케이션에 WebView를 들어가는 미니 쇼핑몰이다.
쇼핑몰은 기존에 운영되던 옆 팀의 결과물이고 이를 타사 어플리케이션의 디자인 가이드에 따라서 적용을 하면 된다.
배포는 Netlify를 통해서 될 것이고 규모가 작을 것이라고 했다.

그래서 선택하게 된 것은 Vite(React), Tanstack-Query, Zustand, Vanilla Extract이다.
검색엔진 최적화가 필요하지 않고, 페이지 캐싱이 필요하지 않은 상황이며, 프로젝트 규모가 작기에 Vite를 통해서 React로 SPA 프로젝트가 부합했다.
API는 한번 캐싱한 것을 여러 페이지에서도 사용했어야 했기에 Tanstack-Query를 택했다.
Zustand는 프로젝트 도중에 결제 정보를 보유하고 결제를 진행하거나 실패했을 시 그대로 불러와야 했었고, 때로는 React cycle에 따라서 렌더링이 필요했기에 사용했다.
CSS library는 Vanilla-Extract를 채택했다. 기존 CSS-in-JS들은 JS로 번들되기에 환경이 좋지 않은 모바일에서 더욱 더 CSS 로드가 느려져 의도치 않은 화면이 중간에 노출될 수 있기에 정적인 CSS 빌드가 필요했고, 타 팀의 신규 서비스가 Vanilla-Extract라서 유지보수를 높이기 위해 채택했다.

소프트적 문제 해결

외부 협력사와 같이 하다보니 프로젝트에 들어가는 인원이 평균의 2배이다.
이렇다보니 소프트 문제가 조금씩 있었다.

유저플로우에 대한 고민

먼저 협력사 어플리케이션을 보면 Android에서는 뒤로가기 버튼이 존재하고 작동을 하지만, iOS에서는 스와이프를 통한 뒤로가기 되지 않는다. 즉, 아이폰 유저는 WebView내부의 버튼을 통해서만 화면을 움직이기에 문제가 없지만 Android 유저들은 뒤로가기 버튼을 클릭하여 이전 화면으로 가면서 유저플로우가 원활하지 않을 수 가 있다.

처음에는 react-router의 history기능만 떼와서(shimmer 이용) useEffect 내부에 beforeUnload 이벤트를 통해서 history stack을 조작하려고 했지만 결과적으로 더 꼬이게 되었다.
따라서 협력사에 native 지원을 요청했지만 내부 방침에 따라서 지원을 못 한다고 답변을 받았기에 내부적으로 해결해야 했다.

그 날 저녁에 WebView라고 생각되는 카카오 선물하기 및 무신사를 들어갔고 마침 개인적으로 와이파이 도시락을 결제해야 했기에 데스크탑 프로세스를 분석했다.

  • 카카오 및 무신사 WebView는 화면이 이동이 되면서 history stack이 쌓이고 Android의 뒤로가기 버튼 또는 화면 뒤로가기 아이콘은 history.back()을 사용하는 것을 알았다.
  • 데스크탑 버전의 와이파이 도시락 또한 뒤로가기 클릭 위와 동일하게 움직이지만 결제 정보 입력란 및 결제비밀번호 입력 란에서 이미 구매한 정보가 있다면 해당 화면에 alert를 띄우고 초기화면 이동을 하고 있다.

위 두 정보를 가지고 기획자와 회의를 했으면 history 조작 자체가 web browser에서 지원되지 않는 점을 설명하여 다음과 같이 유저플로우를 같이 수정했다.

  • 몇몇 페이지의 뒤로가기 아이콘을 history.push() 이동. 왜냐하면 본인인증 후 상세로 다시 돌아오는 프로세스가 있는 데, 이 때 history.back()을 진행하면 PASS로 넘어가면서 iOS에서는 어플을 꺼야만 하는 상황이 있기 때문이다.
  • 결제 비밀번호 입력란과 같이 자금 결제를 유도하는 창으로 돌아가지 않게 해당 페이지들은 history.replacestate()를 이용하여 뒤로가기 시 미노출
  • 이외 나머지 페이지는 전부 history.back() 사용

어느 정도 타협접을 본 상태여서 만족하지는 않았지만 중요한 화면 재노출로 인한 불상사는 방지했다.

P.S. 운영되던 4개월 동한 유저플로우로 인한 CS가 접수되지 않았다는 것을 기획자를 통해서 확인할 수 있었다.

기술적 문제 해결

모바일 네트워크의 속도

모바일 네트워크가 유선보다 느리며 모바일 브라우저의 성능 또한 데스크탑의 성능보다는 좋지 않다고 알고 있다.
이런 경험은 반응형 디자인을 적용한 프로젝트에서 성능 측정 시 많이 봤으며 이는 lighthouse 성능 측정 후 최하단 부분에서도 확인할 수 있다.

따라서, 같은 환경을 브라우저 개발 자체에서 확인할 수 있도록 한국 3G사용자 평균 네트워킹 속도를 검색하여 개발자 도구에 값을 넣고 개발을 시작했다. 이를 통해서 다음 문제들을 발견할 수 있었다.

1. 이미지의 로딩 속도

프로젝트 대부분의 input 형태, 아이콘, 이미지는 전부 이미지 파일 형식이다. webp형식이라서 크게 신경 쓰고 있지 않았지만 event 발생으로 변해야 할 input 형태가 느리게 변경됨에 따라 사용자 반응이 되었는 지 알기 어렵다고 느껴졌다.
당시 나는 CDN에 caching을 기대할 수 없었고, Next.js같은 프로젝트가 아니기에 페이지 caching 또한 되지 않았기에 image preload기법을 사용했다.

페이지 초기 로드 시, 유저 반응에 의해 변경되어야 하는 이미지는 useEffect를 통해서 먼저 preload를 했고, 이를 통해서 유저 반응에 즉각적으로 반응하는 형태를 만들 수 있었다.

2. 폰트의 로딩 속도

속도가 저하된 상태에서 개발하다 보니 폰트 또한 페이지 로드보다 미세하게 느리게 받아와 화면이 변경되는 형태를 확인했다. 이를 검색 했을 때 FOUT 현상에 해당되었다.

  • Flash Of Unstyled Text(FOUT): 기본 본트로 보이다가 뒤늦게 적용되는 현상
  • Flash Of Invisible Text(FOIT): 폰트 자체가 로딩이 되어서 뒤늦게 나타나는 현상

따라서, index.html에다가 첫 페이지 로드 시 필요한 font속성에 preload값을 적용하여 우선적으로 로드하여 FOUT 현상을 해결했다.

P.S. 당시 적용 후 4개월이 지난 시점에 그룹 스터디를 통해서 font 자체에 몇몇 기능을 통해서 더 다양하게 해결할 수 있다는 것을 알았다. 근무 시간에 시간이 있으면 이에 해당하는지 분석하고 적용을 하면 더 좋을 것 같다

3. 빌드 용량 증가에 따른 속도(Suspense 붙이기)

노트북에 연결되어 있는 속도보다 느리게 작업을 하다보니 프로젝트 규모가 커질 수록 새로고침의 속도가 늦어지는 것을 확인할 수 있었다. 운영 단계에서 새로고침 자체가 없지만 첫 페이지 진입이 늦어지는 것 동일하게 볼 수 있기에 route별 lazy import를 진행했다. 다만, 앱과 같은 원할한 동작을 원했기에 몇몇 페이지는 lazy import자체를 사용하지 않아서 첫 로드 시 바로 가져올 수 있게 했다.

또한, lazy import를 활용할 수 있게 를 활용하여 로딩처리를 했고, 이를 설정하면서 대부분의 조회 쪽은 tanstack-query의 useSuspenseQuery를 통하여 조회 및 에러 처리까지 하여 만일의 상황을 대비했다.

P.S. 최근 트렌트 글로 lazy import된 컴포넌트를 특정 상황에서 load하는 글을 봤는 데 이 또한 시간이 있으면 분석하고 적용하면 더 좋을 것 같다.

iOS 노치 문제

iPhone 상단에는 노치 및 하단 액션바가 존재하는 데 이 부분을 고려하여 화면을 조정해야 한다.
이를 해결하기 위해서 safe-area-inset-${position}으로 시작하는 css값을 통해서 화면을 조정할 수 있다.

env(safe-area-inset-top)
env(safe-area-inset-right)
env(safe-area-inset-bottom)
env(safe-area-inset-left)

문제는 해결을 할 수 있으나 확인은 어렵다. 왜냐하면 타사 개발 어플리케이션을 사용하여면 허가서를 신청하고 타사 사내 와이파이를 사용해야지만 이용할 수 있기 때문이다. 즉, 내 자리에서는 확인이 불가하기에 매번 요청해야 한다.

이런 상황이 불편하여 사내 native 개발자와 가볍게 이야기했고 내 상황을 고려허여 로컬 simulator를 띄울 수 있게 환경 설정 해주시고, 사내 테스트 iPhone에 미사용 앱을 현재 프로젝트에 맞게 전환시켜 내 자리에서도 체크할 수 있게 만들어 주셨다. 설치 환경 또한 협업사 native개발자와의 대화를 통해서 최대한 비슷하게 구성을 했고 몇번 크로스 체크를 통해서 동일한 환경을 만들어 낼 수 있었다.
이를 통해 iPhone 기종별 노치는 해결할 수 있었다.
다만, 본인인증(PASS)는 내가 조작할 수 없었고 협력사 방침에 따르면 기술적 지원은 어렵다고 하여 해당 화면은 수정할 수 없었다.

iOS input 확대 현상

개발폰이 iPhoneSE다 보니 확인할 수 있었던 상황이다. Input창을 클릭하면 확대하는 현상이 있었고 사용자 편의성을 위하여 추가된 기능이만 현재 상황과 맞지 않아서 이 StackOverflow글을 보고 index.html에 meta name="viewport"항목에 viewport-fit=cover 속성을 추가하여 해결했다.

여담으로, 타팀에서 운영 중인 앱에서는 사용자 나이대가 높기에 해당 기능을 활성화 했다고 한다.

마무리

혼자서 유저화면을 처음부터 끝까지 작성하면서 백오피스에서는 경험하지 못 하는 문제들을 만났고 해결했다.
출시 이후 광고비를 쓰지 않음에서 최근까지의 월 평균 2억 매출이 나오고, 프론트 수정 배포 0회를 계속 유지하고 있는 것을 나름 뿌듯하게 생각한다.
최근 근황을 봤을 때는 비슷한 성격의 프로젝트를 진행하기 위해서 노력 중이라고 했는데, 이 때가 된다면 이번 프로젝트에서 부족했던 부분을 조금 더 보완하고 싶다.

profile
꾸준히 공부하자

0개의 댓글