카톡 벤치마킹해서 채팅 퍼포먼스 개선하기 | 퀘스트에 참여하세요

카톡 벤치마킹해서 채팅 퍼포먼스 개선하기
인사이트/로그개발 관련

카톡 벤치마킹해서 채팅 퍼포먼스 개선하기

#카카오톡만들기 #채팅어플만들기 #어플개선하기 #어플속도개선 #코드효율화 #채팅자체구현 #SQLite #MongoDb #리액트네이티브속도 #RN속도개선프로젝트

작성일 : 23.08.16 17:27

0

2

0

👉 본문을 50%이상을 읽으면 '여기까지다' 퀘스트가 완료됩니다(로그인 필수)

맞습니다. 킹정합니다. 그래서 이번 기회에 수정했습니다.

이번주 일요일에 모바일앱의 채팅기능이 업그레이드 되어 양대 마켓에서 업데이트시 새로운 버전으로 이용가능합니다.

여러분이 말하시는 여러가지 문제점을 직시하고 해결하고자 하였습니다.

  1. 1. 푸시 타고 들어왔는데, 메시지에는 갱신된 메시지 안보인다.

  2. 2. 새로고침 눌렀는데 새로고침이 안된다.

  3. 3. 메시지가 추가되거나 전송누르면 화면이 너무 느리다.

원래는 2023년 8월내내 개발이 필요할 것이라고 예상(한달정도 소요)하였지만 ,

생각보다 빠르게 여러 테스트가 안정적으로 완료되어 생각이 무색하게 바로 업데이트해버렸습니다.

1. 기존 모바일 앱의 채팅상의 문제점

"앱의 모든 버벅임은 리덕스(글로벌 상태관리)에 1차적인 이유가 있다"

리덕스가 뭐야라고 하시는 비개발자분들도 있으시지만, 글로벌 상태관리를 모르시는 개발자분들은 없으실것입니다.

특히 리액트를 위시로 한 상태관리개념을 도입하고 있는 모든 프레임워크들은 글로벌 상태관리가 필수이니까요

리덕스일수도 , 다른 무언가의 솔루션일 수도 있지만, 글로벌 상태관리라고 합시다.

렛플도 글로벌 상태관리를 사용하고 있습니다.

아래 유저_리듀서(user_reducer)내에 여러가지 갖가지 변수들을 저장하고, 이를 통해서 화면에 뿌릴 때 사용합니다.

리덕스는 🐕 편하다

리덕스는 세팅하기가 진짜 그지같긴 한데요. 한번 세팅하면 사용하기 넘 편합니다.

상태값을 여러 변수로 던져주지 않아도, 띡 불러오면 어느덧 상태가 잘 바뀌곤 합니다.

원래 렛플도 리덕스로 한 5개정도 상태관리하려고 했는데, 너무 편해서 특히 채팅쪽은 한 10개정도 정도 사용중입니다.

근데 앱은 왜 리덕스 이따구냐?!

우리 리덕스가 왜 앱에서는 금쪽이가 되었는지 모르겠습니다.

웹에서는 그렇게 천사같은 애가 없고 , 알아서 잘 상태관리 해주는 애가,

버전을 높여도 선생님(플러그인)을 붙여줘도, 내가 원하는 대로 갱신되지 않습니다.

모바일앱을 개발하면서 나만 이럴거야로 나를 자기암시해놓고 출시하는것도 한두번이 아니었죠.

아마 내 잘못이겠지?! 리덕스에서 벗어나자

100% 제 잘못이죠. 아마 이 리덕스에 너무 복잡하게 데이터를 넣어놓은 것이 문제가 아닐까 생각이 듭니다.

채팅방이 있으면, 그 방의 채팅내역까지 모두 리덕스에 넣다보니,

우리 리덕스가 금쪽이가 된것이 아닐까 추측을 하게 됩니다.(근데 웹은 왜 잘되는데 열받게)

리덕스를 여러가지로 한번 테스트를 해보았으나, 돌아오는 건 실패뿐이었습니다.

여러번 검토하였고, 결과는 채팅에서는 리덕스를 최대한 쓰지 말자 인거죠.

그러면 어떻게 해야하나? 여러가지 방법을 고민해봤지만, 역시 개선의 단서를 찾는건 1위 업체가 가장 유력하죠.

그래 "아이 러브 라이언!!!"

카카오톡은 전체 메시지를 앱내 저장하고, 필요한 부분이나 업데이트가 있을때만 추가로 불러들이는 방식으로 서비스가 이루어져 있습니다.

그러다보니 인터넷 연결이 없어도 , 채팅 메시지 불러오는것 많이 보셨을 텐데요

우리도 그렇게 하면 되지 !!! 다들 그렇게 하는 이유가 있었겠죠 . 다들 고민했다면, 우리도 고민없이 따라가는게 맞는 것 같습니다.

성능따윈 라이언형님을 믿고 따라하가, 물론 구현방법은 다르겠지만, 지금보다는 나아지겠죠.

2. 방향은 알았으니 일단 코딩부터 하고 보자

SQLite를 이렇게까지 빡세게 써본적은 없어서 어떤식으로 테이블 구성할지 감도 안오기도 하고,

괜히 내 분에 안 맞는 채팅 시스템 만드려고 고민하는가 싶기도 하는데 일단 코딩부터 하고봅시다.

사실상 채팅방은 몽고 DB로 구성되어있어서, noSQL이지만, 앱의 데이터베이스는 SQLite이기 때문에 , RDB를 따르고 있습니다.

테이블은 일단 베끼자

두개의 DB가 형태는 다르지만, 테이블과 필드 구성은 거의 동일하게 진행합니다.

약간 더 추가되는 필드가 있다면 시간관련한 필드정도만 추가하였습니다. (UPDATED_TIME 정도만 추가되었네요)

기존 채팅의 몽고DB의 구성은,

프로필 + 채팅 + 메시지 이렇게 세개의 테이블이었다면, 모바일은 채팅+메시지로만 구성합니다.

프로필은 너무 많이 바뀌는 데이터라서 가지고 있다면 더 속도에 저하가 있을만한 테이블이기도 하구요

최신성이 보장되어야 해서, 저장하지 않습니다.

통신을 바꾸자

1) 기존방식에서 변경되는 통신

로그인시에 채팅과 관련한 전체 데이터를 불러와서, 리듀서에 저장합니다.

글로벌 상태값인 리덕스에 저장하고, 메시지나 방이 추가/삭제 되면 이 상태를 다시 리덕스에 저장하여,

이 리덕스 값을 저장하여 채팅방 혹은 채팅방내 대화를 업데이트 합니다.

이경우, 리덕스가 엄청난 데이터를 가지고 있기 때문에 , 메시지를 하나만 추가해줘도 난리 아닌 난리가 납니다

메시지 하나가 바뀐건데, 상태값이 아예 바뀐것이 때문에 전체 렌더링을 해줘야 하는 상황이 발생합니다.

그래서 뭔가 버벅임 ㅠㅠ

2) 신규로 개발해야 하는 통신방식

로그인시에 채팅관련한 데이터를 불러오는 것은 맞으나, 리듀서에 저장하지 않습니다.

그대신 모바일내 저장공간에 저장합니다.

채팅방

기존에 저장한 채팅방이 유효하지 않을 수 있으므로, 채팅방이 유효한지 체크하여 채팅방을 삭제하거나 업데이트, 신규로 입력합니다.

유저가 채팅탭에 들어왔을 때 이를 반영한 모바일 DB(SQLite)를 불러옵니다.

디바이스내에 DB가 최신성을 반영하지 못할 수 있으므로 새로고침 UX을 제공하고, 이를 누르면

다시 서버에서 채팅방 리스트를 가지고와서, 디바이스내 DB를 업데이트 합니다.

메시지

메시지 또한 디바이스 DB에 저장합니다.

처음 불러올때 약 20개정도의 메시지를 저장하고, 추가 불러올경우 추가 30여개의 메시지를 추가 저장합니다.

이 모든 메시지는 디바이스내에 저장하므로, 화면에 들어올경우 디바이스내 메시지를 호출하여 보여줍니다.

메시지가 추가될경우, 디바이스내에 저장을 하지만, 우선 화면내에는 바로 보여줘야하기 때문에 저장함과 보여줌을 동시에 처리합니다.

이벤트를 분리하자

채팅의 경우, 자바스크립트의 웹소켓을 사용하고 있습니다.

웹소켓은 이벤트가 수신되면, 서버에서 이벤트를 수신하여 브라우저에서 보내주는 역할을 하고 있습니다.

지금까지 이벤트는 각 지면별로 이벤트가 구성된것이 아닌 통합 이벤트였습니다.

유저가 어디에나 있던지 간에 동일한 이벤트를 받는 방식이었습니다.

A화면 - a,b,c,d 이벤트 처리

B화면 - a,b 이벤트 처리

C화면 - a,b 이벤트 처리

.

.

.

.

이러다보니, 이벤트를 해제했다가 다시 수신하는 등의 액션이 추가로 필요한 상황이고,

각 화면에 들어갈때마다 이것을 반복하는 ㅎㅎㅎㅎㅎㅎ 구조였습니다.

느릴 수 밖에 없었죠

지금은 각 화면별로 이벤트를 분리해서, 해지하고 관계 맺는 내용을 상당히 줄여버렸습니다.

그리고 이벤트가 맺어졌는지 끊어졌는지 고민할 필요가 없는거죠. 어쨋든 수신은 되게 만들었습니다

그리고 이벤트 수신받는 화면도 최소화해서 공통 펑션화했습니다.

A화면 - a,b,c,d 이벤트 처리

B화면 - e,f 이벤트 처리

C화면 - g,h 이벤트 처리

FLAT LIST와 FastImage를 쓰자

리액트 네이티브에서 속도를 높여주는 수단으로 자주사용하는것이 FLAT LISTFastImage 입니다.

FLAT LIST는 반복되는 화면을 그려줄때 최적화해서 그려주게 되고,

FastImage는 이미지 로딩을 최적화주는 라이브러리입니다.

안쓰고 있었습니다. 당연히 쓰고 있을 줄 알았는데, 채팅에는 안쓰고 있더군요. ㅠㅠㅠ 진짜 미쳤나봅니다.

이와 같이 이런 여러가지 개선을 모두 적용했습니다.

렛플을 통해서 스트레스 받으시면서 사이드프로젝트하지 않도록 최선을 다하겠습니다.

문제 있으시면 언제나 말씀해주세요. 진짜 빨리 업데이트 합니다.