본문 바로가기
개발 이야기/안드로이드 개발

화면이 뭔가 버벅거리는거 같다. 이유가 무엇일까?

by 정선한 2024. 6. 26.
728x90
반응형

안드로이드에서 앱 개발을 하다 보면 뭔가 화면의 렌더링 속도가 생각보다 길다고 느껴질 때가 있다.
데이터가 많은 것 같지도 않고 무언가 대단한 화면이 아닌데, 왜 오래 걸릴까? 싶은 생각이 듭니다.

이럴 때 Android Studio 개발 툴에서 원인이 무엇인지 찾아볼 수가 있는데요. 오늘은 원인을 파악하기까지의 과정을 담아보려고 합니다.

일단 화면이 어떻게 그려지는지에 대한 구조적 이해가 필요할 텐데요.
이 부분은 안드로이드 공식문서의 그래픽 카테고리에서 확인이 가능합니다.

 

그래픽  |  Android 오픈소스 프로젝트  |  Android Open Source Project

그래픽 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Android 프레임워크는 그래픽 드라이버의 제조업체 구현과 상호작용하는 다양한 2D 및 3D용 그래픽 렌더

source.android.com

화면을 그리는 구조적인 아키텍처와 화면이 로드되는데 까지의 View, Manager 그 외 기타 많은 내용을 문서에서는 다루고 있습니다.
이 부분도 꽤나 심오한 내용들이 많아서 차차 포스팅을 진행하긴 하겠지만
오늘은 그래픽 아키텍처와 화면이 로드되는 실제적인 과정을 다루어 보려고 합니다.

디스플레이가 실제로 렌더링 되는 과정

디스플레이가 실제적으로 그려지는 과정을 이해하기 위해서는 기본적으로 BufferQueue에 대해서 이해가 필요합니다.

BufferQueue는 Android 그래픽의 구성요소를 서로 연결시키는 역할을 하고, Producer와 Consumer로 이어지는 Buffer의 순환을 중재하는 Queue입니다. 이는 SurfaceFlinger로 버퍼가 전달되면 모든 요소를 화면에 그립니다.

이 과정이 CPU와 GPU 사이의 통신입니다.

  • CPU
    • 화면을 데이터로 만든다.
  • GPU
    • 화면을 하드웨어에 전달하여 그린다

이 CPU와 GPU 사이의 통신이 BufferQueue에 의해 수행되는 것입니다.

  • Producer -> BufferQueue : queue (생산자가 정의한 화면의 정의를 BufferQueue에 담는다.)
  • BufferQueue -> Consumer : acquire (소비자가 BufferQueue에 담긴 데이터들을 화면에 그린다.)
  • Consumer -> BufferQueue : release (화면에 모두 그려지면 해당 데이터를 소비한 후, 반환한다.)
  • BufferQueue -> Producer : dequeue (소비자로부터 생산자로 전달된 BufferQueue로 부터 사용 가능한 버퍼 요청한다.)

이를테면, CPU (Producer), GPU (Consumer) 라고 보면 될 것 같네요.

그러니까 UI가 버벅거린다고 느껴진다면, CPU, GPU 사이의 통신시간이 다소 길어졌다는 의미이며,
이것을 fps단위로 수치화 한다면 기본 30fps 에서 33ms 이상, 60 fps에서 16ms 이상 걸린다는 의미가 됩니다.

Android Studio 에서 디버깅해보기

그러면 이렇게 ms 단위로 딜레이 되는 것을 찾아야겠죠, 이 부분은 Systrace를 통해서 BufferQueue를 추적해 볼 것입니다.

이 추적과 관련한 가이드도 안드로이드 공식문서에는 있어서 같이 첨부하였습니다.
물론 저도 가이드를 따라서 진행해 보았습니다.

이렇게 CPU에서 스레드 단위로 처리되는 데이터의 양 + 처리속도를 확인해 볼 수 있습니다.

이 Systrace는 안드로이드 디바이스 자체에서 활성화시킬 수도 있습니다.

해당 설정 내용은 이미지로 첨부하였습니다.  제 테스트 디바이스는 갤럭시 S6 Lite라서 삼성 디바이스를 통해 테스트하시는 분들은 설정의 이 부분을 참고하여 활성화시켜주시면 됩니다.

Logcat에서는 Choreographer에서 전달해 주는 log 또한 확인이 가능합니다.

Choreographer           I  Skipped 53 frames!  The application may be doing too much work on its main thread.

너무 명확하게,,, 메인스레드가 일을 너무 많이 하고 있다고 말해주네요, 로그가 귀엽다 싶습니다.

현재 제가 테스트 한 앱 코드에서는 별도 통신 없이 UI만 그려놓고 테스트를 하고 있어서 내부 메인스레드 처리로직 안에 데이터를 많이 생성하고 이를 그리고 있어서 이렇게 뜨는 것 같습니다.

아마 성능테스트를 제대로 해보려면 API통신이 묶이고 코루틴을 통한 처리를 해주면서 스케줄링을 별도로 처리해 준 뒤에 다시 해보아야겠습니다. 그때에는 조금 더 명확한 결과를 얻을 수 있겠네요.

아마 이 퍼포먼스 테스트를 주제로 몇 번 더 포스팅을 해야 할 것 같습니다.
이번에 찾아보면서 느낀 부분인데 생각보다 딥한 영역인 것 같다는 생각이 듭니다.

728x90
반응형