이 포스트는 레이아웃에 관해 다루기 때문에 UI/UX 카테고리에 넣어야 하나도 싶지만, 결론적으로 앱의 성능을 높이기 위한 레이아웃 최적화 작업이기 때문에 Performace 카테고리로 옮기기로 했다.
우선 첫번째로 안드로이드에서 뷰의 계층이 성능이 어떻게 영향을 주는지에 대해서 더 제대로 이해를 해 보고 싶었다.
상기 내용에 대해서 안드로이드 개발자 문서에서는 아래 정도의 내용으로 레이아웃 계층 문제를 설명하고 있다.
- 모든 뷰는 레이아웃(동사) 및 측정단계를 거쳐 렌더링 된다.
- 레이아웃 및 측정단계에서 측정 단계는 View 객체의 크기와 경계를 결정하고, 레이아웃 단계는 이 객체를 배치할 위치를 결정.
- 뷰가 setText 등의 작업에 의해 사이즈를 조절해야 하는 경우 다시 이 레이아웃 및 측정단계를 거치기 때문에 비용이 발생한다.
- 이런 일련의 UI 작업들은 Worker Thread에서 수행할 수 없기 때문에 최대한 작업을 최적화 하는 것이 좋다.
- 계층을 가진 레이아웃의 경우 하위 레이아웃이 변경될 때, 상위 요소 크기에 영향을 주지 않는 객체에 이를 때까지 레이아웃 비용을 발생시킬 수 있다. > 이를 계층 구조를 평평하게 할 수록 단축시킬 수 있다.
그리고 UI 성능에 관한 여러 포스팅에서 자주 등장하는 개념인 Double Texation(이중과세)에 대해 별도로 짚자면
이중과세란 변화시킨 뷰만 측정 단계를 거치는 것이 아니라, 이와 연관된 뷰도 동일하게 측정 단계를 거치는 것을 말한다.
이 정도로 안드로이드가 View를 그리는 방식과 이에 따르는 사이드 이펙트들에 대해 따져봤다면, 그렇다면 이제 이를 보완할 수 있는 계층구조를 줄이는 방법 중 하나인 merge 태그 사용에 대해 정리하겠다.
보통 레이아웃 작업을 하다 보면, 별도의 레이아웃을 선언하고, 이를 include 태그로 다른 레이아웃에 집어넣는 작업을 보통 해 왔을 가능성이 높다.
다만 이 include 태그를 이용하는 작업하게 되면, 컴파일러가 컴파일을 하게 되면 아래와 같은 레이아웃이 만들어 지게 된다는 것이 문제다.
사실 필요로 할 것은 텍스트 뷰가 전부인데, 불필요한 ConstraintLayout이 이중으로 텍스트 뷰를 감싸게 되는 것이다.
우리는 계층 구조를 무조건 줄여야 하는 미션을 가지고 있기에, 이는 당연히 피할 수 있다면 피하는 것이 상책이다.
여기에는 아주 간단한 솔루션이 있는데, 바로 merge 태그로 child layout을 만드는 것이다.
기존에 텍스트 뷰를 감싸던 ConstraintLayout을 merge 태그(parentTag로는 include되는 부모 Layout을 지정)로 대체하고 나면
아래와 같이 새로운 계층 없이 TextView만을 대상 레이아웃에 집어넣는 모습을 확인할 수 있다.
레이아웃 계층에 대해서 디바이스 성능에 따라 이를 대수롭게 여기지 않는 경우도 다수 생길 수 있을 것이다.
하지만 안드로이드가 가지는 특징 중 하나인 기기 파편화를 생각해 보았을 때, 조금이라도 최적화 된 앱은 낮은 성능의 기기에서도 좋은 사용자 경험을 안길 수 있을 것이고, 더불어 고성능 기기에서는 말 할것도 없이 부드러운 사용자 경험을 가져다 줄 것임에는 분명하다.
더불어 계층구조가 실로 깊게 들어가게 되는 경우, 레이아웃 드로잉의 비용은 이중 과세문제로 인해 2의 n승으로 늘어날 수 있는 것도 꼭 염두해 두고 개발을 해야만 하겠다!
< 참조 >
'ANDROID > Performance' 카테고리의 다른 글
[Android] Android lifecycle과 savedInstanceState (0) | 2021.11.21 |
---|---|
[안드로이드] 구글이 소개하는 메모리 최적화 기법들을 리뷰해보자 (0) | 2020.07.12 |
[안드로이드] 안드로이드 스튜디오의 Inspect Code로 프로젝트 자가진단하기 (0) | 2019.08.26 |
[안드로이드] 안드로이드 오버드로우 개선 - 레이아웃의 background를 확인하자 (0) | 2018.05.04 |
[안드로이드] 안드로이드 앱 메모리 최적화 - 이미지뷰 drawable 비우기 (0) | 2018.03.16 |