하반기에 다양한 컨퍼런스들이 개최되고 마무리되면서 유튜브에도 영상들이 올라오고 있다. 오늘은 당근 테크 밋업 영상 중 김태희 개발자님의 아니, 여기도 웹뷰였어요? 라는 주제의 영상을 보고 알게 된 점이나 재밌게 본 점을 정리했다.
영상은 당근 앱의 2탭의 동네생활에서 피드나 글 쓰기, 수정 등의 화면이 전부 웹뷰 기반이다!로 시작한다. 그리고 SSR, CSR의 차이, 웹뷰에 대한 이야기, 새로고침을 넣는데 생기는 다양한 이슈들에 대한 얘기를 들을 수 있었다.
웹뷰라는 건 간단히 말해 앱에서 보여지는 웹사이트다. 어플의 경우 어떤 기능을 추가하거나 실험을 하게 되면 사용자가 앱을 업데이트해야 한다. 하지만 웹뷰를 도입할 경우 특별한 업데이트 없이도 추가된 기능을 사용할 수 있다는 장점이 있다. 당근 동네생활에서도 역시 다양한 실험을 해보고 싶어서 웹뷰 전환을 결정했다.
웹뷰로 전환할 경우 아무래도 네이티브보다 느릴 수밖에 없는데 CSR WebApp 에서 문제가 될만한 부분은 ...
CDN이 외국을 다녀오는 경우, 번들을 받는데 인터넷이 느릴 경우인데 이 문제의 경우 번들은 lazy loading으로 쪼개면 되고 CDN 문제는 AWS cloudfrond/s3 기반으로 배포되도록 직접 빌드 파이프라인을 구축하는 방법으로 리젼 문제를 해결할 수 있다고 한다. ( 후자 무슨 말인지 이해 못 함 )
기존 CSR 방식의 경우 화면을 그릴 준비가 다 된 후에 API를 호출하는데 사용자 네트워크 상황에 따라서 API요청과 응답 자체가 느릴 수 있었다.
CSR의 이런 문제점 때문에 네이티브만한 성능이 나오지 않을 것 같아서 SSR 도입을 결정.
SSR을 도입하는데 next.js를 쓰는 게 아니라 fastify + vite + React DOM Server 기반으로 직접 구축했다고 한다. next.js의 경우 versel이랑 강결합되어 있는 편인데 사내에서 versel을 안 쓰려고 하는 추세였다구...
이 부분을 들으면서 그동안 이 둘의 차이를 이해하려고 찾아봤던 자료들 중 제일 이해가 잘 가는 것 같았다. 브라우저가 API를 직접 부르느냐 아니냐의 큰 차이점.
CSR : js, css 다 다운받고 렌더링 하면서 API를 브라우저가 호출. (cross domain)
SSR : 렌더링에 필요한 API 요청 서버에서 하고 나서 렌더링 된 HTML 갖다줌.
여기서 API호출 cross domain 같은 경우 이거 쓸 수 있냐는 물음이 무조건 발생하는데 이런 CORS 관련 preflight 요청이 100~200ms 정도의 지연이 발생한다고 한다. API 호출 하나의 경우 이 정도인데 만약 요청할 API 가 많다? 그럼 더 많은 지연이 발생하는 것. 이런 점이 없다는 게 SSR의 장점이기도 하고 API 호출을 서버에서 한다는 부분에서 사용자의 네트워크 환경을 덜 탄다는 장점도 있다. CSR에서 API 하나를 부르다가 다른 걸 부르는데 네트워크 상태가 안 좋아지면서 느려지면.. 영원히.. 화면이 안 떠..
다만 이렇게 API를 부르다가 하나가 느린 경우더라도 CSR의 경우 로딩스피너 같은 UI를 통해서 사용자에게 아직 로딩중이다라고 인식시킬 수 있는 반면 SSR의 경우 API 요청이 다 끝나야 화면이 떠서 오히려 CSR보다 늦게 뜰 수도 있다고 한다.
이쯤에서 내 표정 : 이거 완전 도르마무 아녀.😮
근데 당근에서는 이걸 해결하려고 Streaming SSR을 도입했다고 한다. API 호출 때문에 화면이 늦게 뜨는 걸 대비하기 위해서 화면을 한 번에 그리는 게 아니라 쪼개서!! 그리는 방식이라고 한다. API 호출과 관련 없는 부분은 호출하기 전에 그려버리고 외부 요소에 의해서 렌더링 되는 부분들은 차근차근 그리는 거라고.
Suspense 로 묶이지 않은 부분을 셸이라고 부르는데 셸이 먼저 그려지고 차근차근 Suspense 로 묶인 부분들이 스트리밍되면서 렌더링된다고 한다. 결국 CSR에서 로딩스피너를 보여주던 경험가 비슷해진다고. 신기하다.😮😮
CSR의 경우 별도의 Application Server 가 없어서 모니터링 해야 하는 범위가 적은 편인데 SSR을 하게 되면 별도의 요청을 처리하는 서버가 있을 거고 그럼 서버의 로그를 봐야 하고 트래픽에 따라서 CPU나 메모리가 안 밀리고 있는지 뭐 그런 걸 확인해줘야 한다고 한다. ( 무슨 소리쥐... 😯 )
아무튼 SSR의 도입을 하려면 고민해야 할 부분이 있다는 점인 건 알겠다.
안드로이드 사용자로서 앱을 껐다 키는게 일상이니까 웹뷰의 새로운 버전이 그냥! 자연스럽게 전파될 거라고 생각했는데 IOS 사용자의 경우 끄는 게 아니라 그냥 백그라운드에 넣어놨다가 띄워서 쓰는 게 일반적이라 전파가 안 되는 문제가 발생했다고. 오... 그러네.
이 부분은 내부에서 버전의 값을 전역변수로 갖고 있게 한 다음에 내가 쓰고 있는 버전과 서버가 주는 버전이 같은지 다른지 체크해서 다르면 새로고침을 유도하는 스낵바를 띄우는 방법을 사용했다고 한다. 근데 여기서 발생할 수 있는 문제가 사용자가 만약 이때 네트워크가 안 좋다면?? 먹통이 될 거라고. (웹뷰를 사용하게 될 경우 지하철이나 엘리베이트 같은 네트워크가 불안정한 대응을 해줘야 한다고 한다.) 그래서 온라인, 오프라인을 확인하는 훅을 만들어서 오프라인일 경우 메시지를 주는 걸 택했다고 한다.
와, 제대로 알아들을 수 있던 부분 반, 아직 잘 모르겠는 부분 반이긴 했지만 당근 실무에서 사용자에게 더 좋은 경험을 주기 위해 우당탕탕 웹뷰, SSR 도입기를 들으니까 마냥 재미있었다.
CSR과 SSR의 API 호출 차이점, 앱의 경우 안드로이드, IOS 유저들의 행동 차이로도 만들어질 수 있는 문제점이 존재한다는 사실, 그리고 내가 모르는 부분들이 아직도 무궁무진하다는 현실도! 30분 간의 영상이었지만 순식간에 지나갔다. 다른 얘기들도 즐겁게 들어보고 싶다.