본문 바로가기
프로그래밍 개발/IT 서비스 개발 운영

下 편: 동남아 국가 인프라를 고려한 서비스의 기술적 개선 과정

by Jinseok Kim 2023. 9. 22.
반응형

下 편: 동남아 국가 인프라를 고려한 서비스의 기술적 개선 과정

 

上 편에서 앞서 인도네시아(동남아) 국가 인프라 상황과 스마트폰 보급 상황 그리고 국내 상황과의 차이점 등등을 전반적으로 알아보았습니다.

 

上 편: 동남아 국가 인프라를 고려한 성능 최적화 개선 과정

上 편: 동남아 국가 인프라를 고려한 성능 최적화 개선 과정 현재 서비스 중인 MyVenus는 인도네시아 중심으로 동남아 국가들을 타겟팅한 뷰티 플랫폼 서비스 App입니다. 제 개발자 커리어의 첫 서

k0502s.tistory.com

 

 

 

다시 정리하자면 동남아(인도네시아) 국가의 인프라 및 상황은 아래와 같습니다.

동남아(인도네시아) 국가의 인프라 및 상황

1. 국내보다 불안정한 인터넷 환경.

2. 대략 90%가 Android 디바이스, 나머지 10%는 iOS 디바이스.

3. Android 디바이스에서도 종류가 천차만별, 그리고 저가형 저사양 디바이스 사용이 많음.

 

 

이번 下 편에서는 이 동남아 국가의 인프라를 고여한 개발/운영 측면에서의 기술적 개선 과정을 기록하고자 합니다.

 

 

일단 크게 세 가지로 주제를 나누어 보았습니다.

동남아 서비스를 고려한 개선을 위한 해결 주제

1. 국내보다 불안정한 인터넷 환경 고려와 기술 사용의 보수적인 검토

2. 저사양, 저가형 Android 디바이스를 고려한 기술적인 최적화


3. 성능 테스트, 에러 이슈 대응 프로세스 정립

 

지금 현재 MyVenus 서비스의 상황은 위의 세 가지 해결 주제를 하나하나 해결해 나가 서비스의 안정 단계까지 갔다고 생각합니다. 과정을 거치면서 국내의 서비스 운영과 다른 많은 것을 느끼고 배우게 된 것이 가치 있었던 경험이었습니다.

 

개인적으로 개발자로서 인도네시아 동남아 국가들의 저사양 디바이스, 국내보다 떨어지는 인프라 환경 등등 이러한 조건 상황에 대한 대응이다 보니 개발자로서 성능적인 최적화에 더 밀도 있게 접근하고 경험했다는 게 매우 크게 배워갔다고 생각하고 있습니다.

 

 

 

 

 

 

 

 

국내보다 불안정한 인터넷 환경 고려와 기술 사용의 보수적인 검토


인도네시아 및 동남아 국가의 인터넷이 심각하게 느린 것은 아니었습니다. 제가 말하고자 하는 것인 대한민국의 인터넷 속도가 다른 나라에 비해 매우 빠르게 최적화 되어 있기에 매우 보수적으로 기술적인 적용을 개발할 때 고려해야 했었습니다.

 

대한민국은 영토 또한 그렇게 큰 편이 아니라 서울 수도가 아니더라고 인터넷의 구축망 인프라는 매우 잘 되어 있어 많은 신경을 쓰지 않았었지만 인도네시아의 영토는 국내에서도 시차가 다를 만큼 크고 방대했고 자카르타 수도에서 벗어나면 매우 좋지 않은 인터넷 인프라를 가지고 있어 매우 보수적인 접근이 필요했습니다.

 

특히 上 편에서도 소개해드린 것처럼  실제 서비스 런칭 초반에 Firebase Authentication (파이어베이스 인증)을 로그인 및 회원가입에 사용했었는데 국내에서는 아주 잘 작동했던 기능이 인도네시아 현지에서는 인터넷 불안성의 원인으로 인하여 사용을 하지 못할 정도로 작동하지 않는 현상을 발견하게 되었습니다.

 

인프라가 어느 정도 구축되어 있는 인도네시아의 수도 자카르타 도시에서는 많은 이슈가 없었지만 그 외 지방 도시 및 지역에서는 이 같은 돌발 이슈들이 발생하고 이슈에 대한 고객들의 문의 사항들이 다수 발생하기도 하였습니다.

결국 Firebase Authentication (파이어베이스 인증)을 서비스 도중 교체하게 되었습니다. 인도네시아 현지에서 잘 사용하는 SMS 문자 인증 시스템을 유료로 사용하게 되었습니다. 유료라는 단점이 있었지만 교체 이후 제대로 회원가입 시스템이 잘 작동하게 되었습니다.

국내에서는 잘 사용되었던 기술이 해외에서는 안될 수도 있다는 가능성을 알게 된 후 항상 새로운 기술을 도입하게 된다면 동남아 현지에서 잘 작동하며 인증된 기술인지 체크하는 보수적인 검토 프로세스를 가지게 되었습니다.

또한 인터넷이 불안정하다는 것은 앱 내 이미지 로딩, UI 로딩 등등과 같은 사용성이 떨어질 수 있으니 코딩 개발적인 최적화 또한 매우 신경을 써야 했습니다. 이 사항들은 아래 섹션에서 더 깊이 다뤄볼 예정입니다.

 

 

 

 

 

 

저사양, 저가형 Android 디바이스를 고려한 기술적인 최적화와 대응


 

무엇보다 일반적으로 App은 스마트폰 디바이스로 실행되고 사용되는 것이라 PC보다 성능 최적화면에서 더욱 보수적으로 갈 수밖에 없었습니다.

PC에서 웹을 예를 들자면 웹의 기능을 사용하면 할수록 CPU의 사용성은 증가하게 되고 뜨거워지지만 쿨러와 같은 해결책으로 온도를 낮추면서 항상 일정하게 성능을 내는 것이 가능하여 최적화에 많은 공을 들이지 않는 거 같습니다.

 

스마트폰의 고질적인 낮은 성능 대응에 하드웨어/소프트웨어 둘 다 많은 대책들이 있는거 같다.


하지만 스마트폰은 다릅니다. 쿨러가 없다는 것이죠. 동시에 배터리 사용량까지 생각하면 더욱 CPU, GPU 성능을 항상 최대로 사용할 수 없기 때문에 개발을 할 때 성능에 대한 최적화에 더욱 신경을 쓸 수밖에 없는 것이 일반적입니다.

 

iOS의 아이폰은 이런 하드웨어적인 면이 매우 최적화가 잘 되어 있고 기본이 고성능, 고가형이기 때문에 그래도 성능 측면에서 매우 나은 편이었습니다.

 

하지만 제가 운영 중인 서비스의 대부분의 고객들은 90% 정도가 Android 폰이었으며 또 저성능, 저가형의 다양한 브랜드의 기기들이기 때문에 어떤 서비스보다 최적화에 신경을 쓸 수밖에 없었습니다.

저성능, 저가형 디바이스에서 성능이 확연히 떨어지기 때문에 꼭 고려해야하는 상황이었습니다.

 

 

 

아래 보여드릴 기술적인 최적화는 현재 서비스를 구축하여 이뤄주고 있는 App을 개발하기 위한 프레임워크인 React Native 기반으로 앱 내 사용성 개선 위주로 기록하였습니다.

 

크게 3가지 주제로 나누었습니다.

1. 불안정한 인터넷 속도 관련 대응

2. React의 랜더링과 메모이제이션 관련 성능 최적화

3. 그 외 기타 App 자체 최적화

 

 

 

불안정한 인터넷 속도 관련 대응

 

확실히 인터넷 속도나 연결이 불안정하니 앱 내 이미지, 데이터 등등의 캐싱 처리가 중요하게 되었습니다.

그리고 React Native의 Code Push 또한 인터넷 상황을 고려하여 국내와 다르게 일반적이지 않는 방식으로 업데이트되도록 구현하기도 하였습니다.

또 인터넷이 느리다는 것을 고려하여 UI 로딩 또한 사용자에게 어색한 기다림을 주지 않기 위한 노력도 있었습니다.

 

 

1. 이미지 리사이징, 캐싱 최적화

 

사실 일반적인 서비스에서도 이미지 리사이징은 필수입니다. 원본 그대로 CDN URL을 불러온다면 매우 오랜 시간 기다려야 하니 사용성이 많이 떨어지기 때문이죠. 특히 이런 인터넷 상황이 불안정하다면 더욱더 리사이징 최적화는 필요하게 됩니다.

그리고 이미지 캐싱 또한 필요했던 이유는 적용하여 한번 불러온 이미지는 해당 디바이스 기기 내에서는 다시 불러오지 않고 저장하고 있는 이미지를 불러오는 인터넷을 굳이 거칠 필요하가 없기 때문입니다.

 

 

아래와 같이 이미지별로 CDN URL의 파라미터 수치를 계산하여 UI에 표시되는 최적의 비율 사이즈로 이미지를 불러오도록 개발하였습니다.

  const getHospitalBannerImageFileAPI = useCallback(
    (id?: number) => {
      return id
        ? `${baseURL}/files/get/${id}?w=${width * 2}&ar=5:3&f=jpeg`
        : '';
    },
    [baseURL],
  );

 

캐싱 최적화는 react-native-fast-image라는 React Native의 이미지 캐싱의 유명한 라이브러리 기능을 사용하였습니다. 한 번 불러오고 나면 캐싱 처리하게 되어 이미지 로딩에 최적화가 되었습니다.

 

GitHub - DylanVann/react-native-fast-image: 🚩 FastImage, performant React Native image component.

🚩 FastImage, performant React Native image component. - GitHub - DylanVann/react-native-fast-image: 🚩 FastImage, performant React Native image component.

github.com

import FastImage from 'react-native-fast-image'

const YourImage = () => (
    <FastImage
        style={{ width: 200, height: 200 }}
        source={{
            uri: 'https://unsplash.it/400/400?image=1',
            headers: { Authorization: 'someAuthToken' },
            priority: FastImage.priority.normal,
        }}
        resizeMode={FastImage.resizeMode.contain}
    />
)

 

 

2. UI 로딩과 사용성

앱 내 대표 LoadingView

앱 내 UI을 랜더링 하기 전 API 호출하는 데 걸리는 시간이 인터넷이 불안정하면 갑자기 비정상적으로 길어질 수 있으니 사용자에게 기다림에 어색함을 없어야 하는 필요성이 더 필요하게 되었습니다.

그냥 흰 화면이 있다면 사용자는 심리적으로 사용성이 떨어질 수밖에 없기에 특히나 개발할 때 API 속도가 빠르더라도 느려질 수 있다는 가능성을 두고 보수적으로 로딩뷰을 적용시키고 있습니다.

 

사실 제일 베스트 케이스는 스켈레톤 로딩뷰를 구축하는 것인데 현재 앞으로 해야 할 테스크로 남겨두고 있습니다.

 

 

 

 

3. React Native Code push 업데이트 방식

 

 

GitHub - microsoft/react-native-code-push: React Native module for CodePush

React Native module for CodePush. Contribute to microsoft/react-native-code-push development by creating an account on GitHub.

github.com

React Native Code Push을 사용하면 매우 유용한 기능으로 앱 스토어 심사를 거치지 않고도 바로 긴급 수정 사항을 업데이트할 수 있는 기능입니다.

 

Code push의 업데이트 프로세스를 간단하게 소개하자면 App을 사용자가 실행할 때 새롭게 업데이트할 JS 번들 파일 다운로드 유무를 체크하고 난 후 새로 다운 받을 JS 번들 파일이 있다면 JS 번들 파일을 인터넷 원격으로 다운로드합니다.

JS 번들 파일이 앱이 실행 될 동안 다운로드가 완전히 완료된 후 
App 자체를 재실행해야만 다운로드가 완료된 JS 번들 파일이 App 전체적으로 적용되며 업데이트되게 하는 형식입니다.


현재 MyVenus 서비스에서도 App을 업데이트하는데 매우 유용하게 사용하고 있습니다.

국내 서비스는 이렇게 Loading Bar을 띄우고 스플래쉬 화면에서앱의 진행을 멈추고 JS 번들 파일을 다운로드 한다.

일반적으로는 앱을 실행시키고 나서 새롭게 다운로드할 JS 번들 파일이 있다면 App의 스플래쉬 화면에서 잠시 진행 상태를 멈추고 JS 번들 파일을 다운로드하는 Loading Bar을 보여주며 다운로드가 끝나면 강제로 다시 앱이 재실행되며 업데이트가 완료되는 형식입니다.

 


하지만 인터넷이 불안정한 환경을 가지고 있는 인도네시아 국가 특성상 앱을 실행한 후 JS 번들이 모두 다운로드되기를 기다려야 하는 시간이 너무 길었다는 것이었습니다.

 

앱을 멈추지 않고 알럿을 띄어 주었다.

 

그래서 결국 저희 개발팀의 논의 끝에 앱이 실행되면 앱이 스플래쉬 화면에서 멈추는 것이 아닌 사용자가 앱을 정상적으로 사용하게 해 주고 이 사이에 Code Push 업데이트를 위한 JS 번들 파일을 받도록 하고 다운로드가 완료되면 위와 같이 업데이트 완료되었으니 업데이트를 하라는 문구의 알럿과 앱을 재실행하는 확인 버튼을 띄워 주었습니다.

 

사실 이러한 방식은 국내의 몇몇 서비스들이 사용하고 있는 것이 목격되기도 합니다. 하지만 인터넷이 빠른 대한민국에서는 스플래쉬 화면에서 처리하는 것이 사용성 면에서 더 자연스럽게 느껴진다고 생각합니다.

 

이 외로 Code Push에 더 자세한 정보를 알고 싶은 분은 제가 올려둔 Code Push 블로그 포스팅글을 참고하면 좋을 거 같습니다.

 

React Native - 코드 푸쉬(Code Push) 정의 / 개발 환경 세팅 / Staging 환경 세팅

코드 푸쉬(Code Push) 정의 CodePush는 마이크로소프트의 Visual Studio App Center에서 제공하는 서비스 중 하나로, 클라우드 기반의 앱 원격 업데이트 서비스입니다. 원리는 git과 유사하다. git은 코드를 수

k0502s.tistory.com

 

 

 

4. 데이터 상태값 캐싱 처리

 

인터넷이 많이 불안정하다면 최소한으로 인터넷을 사용하는 것을 자제해야 하는 것이 효율적이라고 판단하였습니다. 그래서 앱 내 API을 통해 데이터를 캐싱 처리하는 것이 매우 중요했습니다.

 

예를 들어 스크린이 포커싱 될 때마다 API을 호출시켜 데이터를 가져오다가 인터넷이 갑자기 느려지면 사용성이 매우 떨어지기 때문이죠.

 

지금 MyVenus 서비스 App에서 가장 좋은 예는 시술 탐색 리스트 페이지입니다. 동기적으로 불러오는 많은 종류의 시술/뷰티 카테고리 탭이 존재합니다.

 

많은 시술/뷰티 카테고리 탭 별로 각각 리스트를 보여줘야 하는 시술 탐색 리스트 페이지이다.


만약 이 시술 탐색 리스트 페이지에 진입하였는데 이 많은 탭의 페이지의 데이터를 한꺼번에 불러오면 성능에 문제가 생겨 사용성이 문제가 아니라 사용을 하지 못하고 앱의 성능이 저하되어 앱이 꺼져버릴 정도로 CPU을 과도하게 사용하게 될 겁니다.

 

이 문제를 해결하기 위해서 포커싱 된 탭의 페이지만 API을 호출하여 불러오면 해결이 되지만 기획상 손가락으로 좌우 스와이프 하여 탭 페이지를 탐색할 수 있기에 스와이프를 할 때마다 포커싱 된 API을 호출하고 리스트 데이터를 불러온다면 치명적인 이슈는 아니지만 이 또한 사용성이 떨어지게 되는 것은 마찬가지였습니다.

 

 

 

결국 생각해 낸 것은 포커싱 된 탭 페이지와 양 옆 2개의 리스트 페이지만만 API을 호출하여 데이터를 불러오는 것이었습니다. 그리고 이미 포커싱 되어 불러온 리스트에 다시 포커싱 되어도 다시 API을 호출하지 않고 데이터 상태값을 그대로 유지하고 있는 로직도 추가해야 했습니다.

대신 스와이프가 아닌 탭 자체를 클릭하여 바로 탭 페이지로 이동하는 경우에는 잠깐 로딩뷰가 보이지만 이 정도의 로딩은 사용성에 큰 문제가 아니었으며 이 또한 양 옆으로 리스트를 불러오기 때문에 허용 가능한 경우였습니다.

분명 이 캐싱 처리하는 로직 기능을 구현하는 것은 쉽지 않았지만 구현에 성공하면 사용성과 최적화 두 마리 토끼를 잡는 훌륭한 방법이었습니다.

 

네이버 App 홈 화면 탭 페이지가 이런 식으로 되어 있다는 것에 힌트를 얻게 되었습니다.

 

 

 

이제 좌우로 스와이프 해도 미리 양 옆의 리스트를 불러오게되어 데이터 캐싱 처리가 되면서도 사용성도 좋아졌다.

 

 

 

 

React의 랜더링과 메모이제이션 관련 성능 최적화

React Native도 React와 똑같이 랜더링 최적화가 필요하다.

사실상 랜더링 최적화/메모이제이션 최적화는 가장 중요한 부분이라고 할 수 있습니다.

성능 저하로 인한 사용성 악화의 근본적인 원인이 인도네시아, 동남아 국가의 대부분을 차지하는 저가형, 저사양 디바이스 기기의 사양이 낮은 CPU
라고 볼 수 있습니다.

 

해결 방법으로는 바로 불필요한 랜더링을 발생하는 것을 방지하여 CPU에 최대한 부담감을 주지 않고 사용성 저하를 최대한 막는 방법입니다.

 

불필요한 랜더링을 막기 위해서는 React 프레임워크 Hooks 자체적으로 제공해 주는 메모이제이션 최적화도 하나의 방법입니다.

 

더 자세한 React 랜더링 최적화를 메모이제이션은 아래 잘 정리되어 있는 커뮤니티, 블로그를 참고해 주세요.

 

리액트 렌더링 최적화하는 8가지 방법과 고찰

서론 이 글은 함수형 컴포넌트, 클래스형 컴포넌트 상관없이 공통적으로 적용되는 렌더링 최적화 이야기와 hooks를 사용하는 함수형 컴포넌트에서 구체적으로 어떤 기능들을 사용해 렌더링 최적

cocoder16.tistory.com

 

Memoize!!! 💾 - a react (native) performance guide

Memoize!!! 💾 - a react (native) performance guide. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

 

하지만 무조건 메모이제이션을 사용하자는 것은 아닙니다.

저가형, 저사양 디바이스 기기는 RAM 또한 부족하기에 꼭 필요한 부분만 메모이제이션 최적화를 고려해야 했습니다.

메모이제이션을 통해RAM을 적절하게 사용하여 CPU에 부담감을 최대한 주지 않으면서도  RAM 사용을 남발 하지 않도록 하는 개발을 추구해야 합니다.

오히려 반대로 메모리 누수 또한 고려해야한다는 것을 명심해야합니다.

제일 우선적으로는 기능 구현에 앞서 상태값에 따른 컴포넌트 구조 및 분리 설계를 제대로 고도화하여 불필요한 랜더링을 방지하는 것이 베스트인 것 같습니다.

 



 

MyVenus App 서비스 내에서도 수많은 불필요한 랜더링 최적화가 이뤄졌는데 가장 대표적인 예로 위치 기반 서비스 지도 뷰를 예시로 들겠습니다.

 

시술이 가능한 클리닉을 탐색할 수 있는 위치 기반 서비스 지도 기능입니다.

 

import MapView, { PROVIDER_GOOGLE } from 'react-native-maps'

// ...

<MapView
   onRegionChange={onRegionChange}
   customMapStyle={mapStyle}
   ...
>

위의 MapView 컴포넌트는 지도 뷰를 뿌려주는 컴포넌트입니다.

 

 

사용자가 지도를 제스처하여 서칭할때 onRegionChange 콜백 기능을 통해 들어오는 값을 활용하여 구현하려는 기능을 만들어 놓았습니다.

 

문제는 onRegionChange가 제스쳐 할 때마다 너무 많이 호출되어 onRegionChange에서 들어오는 값을 담는 state 값이 계속 바뀌면서 엄청난 랜더링을 발생시키는 것이 문제였습니다.

 

처음에는 큰 이슈라고 생각하지 않아 프로덕션 배포까지 하면서 신경을 쓰지 않기까지 했습니다. 하지만 어느 날 기능 검토를 하던 중에 Android 폰에서 지도를 사용하면 얼마 지나지 않아 앱을 사용할 수 없을 정도로 CPU을 과도하게 잡아먹어 작동하지 않는 치명적인 이슈를 발견하게 되었습니다. (iOS는 CPU 성능이 워낙 좋아 이슈가 눈에 띄게 발현되지 않아 발견하지 못했습니다)

 

이때 이 성능 이슈를 해결하기 위해 Ref가 필요했습니다. onRegionChange에서 받아낸 지도 위치 값 수치들은 UI View에 실시간으로 표시할 필요가 없었고 이 수치를 통해 특정 이벤트 때 API에 담아 호출만 하면 되었기 때문에 굳이 useState을 이용하여 랜더링을 할 필요 없다는 것을 뒤늦게 깨닫게 되었습니다.

 

ReactJs의 내장 Hooks useRef을 사용하여 onRegionChange가 아무리 호출되어도 useRef을 사용하여 지도 위치 값을 저장하고 있어서 Ref값이 아무리 변동되어도 랜더링이 되지 않아 성능 이슈를 해결하게 되었습니다.

 

	const locationRef = useRef<{latitude: number; longitude: number}>({
            latitude: -6.217811692628187,
            longitude: 106.84085805632431,
  	});
  	const deltaRef = useRef<{latitudeDelta: number; longitudeDelta: number}>({
            latitudeDelta: 0.09180037480303938,
            longitudeDelta: 0.05152387131647629,
  	});


	...


	const onRegionChangeComplete = useCallback(
          (region, details) => {
              locationRef.current = {
                latitude: region?.latitude,
                longitude: region?.longitude,
              };
              deltaRef.current = {
                latitudeDelta: region?.latitudeDelta,
                longitudeDelta: region?.longitudeDelta,
              };
          },
          [],
    );

 

사실 개발에 능숙한 분들이 처음부터 Ref을 사용했겠지만 미숙했던 이 당시 저는 처음부터 생각하지 못했던 것 같았습니다.

 

이 이슈 해결을 통해 위치 기반 서비스 기능을 구현해 보는 경험뿐만 아니라 ReactJS을 프로젝트의 성능 개선을 해보는 경험 또한 해보며 프런트엔드로서 한층 더 성장하는 느낌을 받았습니다.

 

성능 개선을 위하여 ReactJs에 대한 더 깊은 공부와 연구를 자연스럽게 더 하게 되었던 것 같았습니다.

 

 

 

 

 

 

그 외 기타 최적화 요소

 

다른 최적화할 요소들이 많이 있었습니다. 가장 대표적인 부분 3가지 있었습니다

1. React Naitve FlatList 최적화

2. 다운로드 앱 용량 축소

 

1. React Naitve FlatList 최적화

 

A guide to optimizing Flatlists in React Native. | Obytes

A guide to analyzing your Flatlist performance, identifying the bottleneck, and fixing common issues.

www.obytes.com

React Naitve에서 FlatList는 매우 필수적인 내장 컴포넌트입니다. 어떠한 서비스 App에든 데이터 정보를 표시 및 탐색해줄 리스트가 있는데 리스트의 데이터 양이 많고 무거워질수록 성능 저하는 일어날 수밖에 없습니다.

이때 FlatList는 이러한 약점을 보이는 스마트폰 기기에서의 App에서 리스트를 최적화해주는 내장 컴포넌트를 제공합니다.

FlatList로 데이터를 리스트로 뿌려주면 한 번에 모든 데이터를 렌더링 하지 않고 화면에 보이는 부분(혹은 설정한 수만큼의 데이터)만 렌더링 해주는 것이 특징입니다.

MyVenus가 엄청나게 많은 뷰티/시술 상품 그리고 클리닉까지 리스트업 하니 이 컴포넌트는 거의 필수적으로 사용하였습니다.

하지만 FlatList만 쓴다고 헤서 완벽하게 최적화되는 것이 아니기 때문에 FlatList의 공식 Docs를 보면서 상황에 맞게 리스트를 최적화하는 것이 중요할 거 같습니다. 기본적인 기능 말고도 더 많은 기능들을 설정할 수 있기 때문입니다.

 

 

 

2. 다운로드 앱 용량 축소

 

앱을 다운로드하는 APK 용량 또한 줄이는 것이 중요했습니다. 만약 인터넷이 불안정하거나 신호가 약하다면 APK의 용량이 커서 앱을 다운로드하는 시간이 길어지기 때문이지요.

다운로드 시간이 길어지면 다운로드 도중 이탈 유저들이 발생할 수 있다는 가능성에 저희 팀은 최대한 APK 파일의 용량을 줄이기 위하여 조치를 취했으며 현재도 용량이 늘어나지 않도록 하는 기본 프로세스를 탑재하여 서비스 App을 업데이트하고 적용합니다.

예를 들자면

1. 이미지 파일을 넣지 않고 초기 앱 실행 화면에 보이는 이미지가 아니라면 CDN으로 대처.

2. Font 파일을 최대한 사용하지 않는 방법.

3. 쓰지 않는 라이브러리 삭제 라이브러리 대신 코드로 직접 기능 구현

 

 

 

이렇게 기술적인 측면들을 고도화하는 과정들이 해외 서비스라는 특정 조건으로 인하여 최적화는 더 필요시 되었고 더 요구하게 되었던 것 같습니다.
위에서 보여드린 개선 과정뿐만 아니라 앞으로도 더 나은 서비스를 위하여 기술적인 고민을 하며 발전해 나가는 것이 현재 상황입니다.

 

 

 

 

 

 

 

 

성능 테스트, 에러 이슈 대응 프로세스 정립


 

上 편에서도 소개해드린 것처럼 인도네시아는 저사양, 저가격, 다양한 종류의 디바이스를 사용하는 상황이기에 개발 완료 후 성능적인 면을 테스트하거나  이슈들을 트래킹 하는데 더욱더 보수적인 행동을 취할 수밖에 없었습니다.

특히 국내의 스마트폰 성능들이 월등히 더 좋기 때문에 삼성 제품만 쓰더라도 성능이 매우 좋아 기능 테스트를 하는데 크게 성능적인 이슈가 나타나지 않았습니다.

 

그래서 개인적으로 개발을 진행하고 기능을 사용해 보는 테스트를 할 때 일부러 저성능 테스트폰 모델 혹은 과거 본인이 매우 오래전에 쓰던 Android 폰으로 앱을 다운로드하고 구현한 기능들을 사용해 보고 테스트해보습니다.

 

확실히 저성능 스마트폰으로 일부러 기능 테스트를 하면 최적화가 필요한 부분들이 잘 보이며 동시에 인도네시아 현지의 상황의 인프라를 고려한 성능 최적화가 되기에 일석이조였습니다.

 

다양한 디바이스 종류가 있기에 발생하는 이슈 또한 다양했습니다. 각각 다른 소프트웨어 버전, 기기 브랜드별로 있는 고유의 버그 등등 많은 예측 불가능한 이슈들을 트래킹 하여 체크하고 로그에 남기는 것이 꼭 필요했습니다.

이미 국내에서도 서비스를 운영하는데 도입하고 있는 Sentry라는 에러 로그 모니터링 플랫폼을 서비스 App에 세팅하는 것은 저희 서비스에서 더욱더 피할 수 없었습니다.

 

Application Performance Monitoring & Error Tracking Software

Self-hosted and cloud-based application performance monitoring & error tracking that helps software teams see clearer, solve quicker, & learn continuously.

sentry.io

예를 들어 치명적인 이슈들의 에러 로그들을 정리 및 분석하기 위하여 치명적인 이슈 발생 알림 Action 및 Notion에 구체적인 이슈 내용과 버전, 찾은 해결 방법 등등 그때그때 정리해 두는 습관을 들여 더 효율적으로 서비스 운영을 하기 위한 전략을 세우기도 하였습니다.

 

결국 이와 같은 프로세스들을 정립하고 나서 서비스는 더욱 빛을 발했던 거 같습니다.
저성능 디바이스를 기준으로 하는 성능 최적화 작업, 거의 모든 디바이스별, 소프트웨어 버전별 이슈들을 체크 및 로깅하여 일일이 해결하는 것은 매우 힘든 작업들이었지만 그래도 하나하나 해결해 나가고 서비스를 고도화할 수 있다는 것이 매우 가치 있는 일들이었습니다.

 

 

 

 

마무리하며...


위에서 소개드린 개선 과정 말고도 더 상세한 개선 사항들이 있었습니다. 현재도 계속 진행 중이고 이러한 서비스의 기술적인 최적화/고도화는 끝이 나지는 않는다고 생각하고 있습니다.

개인적으로는 개발자로서 정말 많은 기술적인 역량을 얻었고 서비스 운영/개발이라는 시야 또한 정말 많이 넓히게 되었습니다. 저에게 있어 길지 않은 개발자 커리어에서 가장 중요한 순간들이었다고 생각합니다.

 

프론트엔드 개발자로서 앞으로도 더 좋은 서비스로 고도화하여 유저들이 더 좋은 경험과 서비스를 제공하여 보람을 느끼는 것이 앞으로의 목적인 것 같습니다.

 

감사합니다.

 

 

반응형

댓글