[iOS] App thinning에 대해서 설명하시오.

민경준·2023년 12월 14일
1
post-thumbnail

🌟 App Thinning 이란?

애플리케이션이 디바이스에 설치 될 때 앱 스토어와 운영체제가 디바이스에 특성과 환경에 맞게 설치 되도록 하는 최적화 기술이다.
필요한 만큼의 리소스만 설치되도록 하기 때문에 적은 디스크 사용량과 빠른 설치의 이점이 있다.
구성으로 슬라이싱(Slicing), 주문형 리소스(On-Demand Resources), 비트코드(Bitcode)가 있다.

🌟 슬라이싱(Slicing)

우선, 슬라이싱이 뭔지 대략적으로 알고 시작합시다. 이에 대한 한줄 설명을 보자면
"다양한 기기와 운영체제 버전에 대하여 여러 가지 app bundle의 변형(variants)을 생성하고 전달하는 과정" 이라고 합니다.

이 한 줄 설명으로는 정확한 이해를 하기에는 부족합니다. 어떻게 생성하고, 어떻게 전달하는지 그 과정을 세세하게 알아봅시다.
자, 앱 안에는 뭐가 들어 있을까요?

실행 가능한 코드, 리소스들이 들어있네요.
그리고 실행 가능한 코드들에는 32-bit 혹은 64-bit가 있고 이것들은 다시 한번 armv7, armv7s, arm64로 세분화 시킬 수 있습니다.

리소스 같은 경우에는 뭐가 들어있을까요?
아트워크(Artwork)가 들어있고 이 것은 1x, 2x, 3x로 세분화 시킬 수 있으며 다시 한번 iPhone과 iPad로 세분화 시킬 수 있습니다.

게임이나 3D 그래픽 기반을 사용하는 앱 같은 경우에는 OpenGL ES, Metal이 들어있을 수 있겠고 이 또한 High Quality와 Low Quality로 세분화 시킬 수 있습니다.
메모리와 그래픽 성능에 따라 Quality에 차별을 줄 수 있으니 어떤 디바이스에서도 멋지게 보일 수 있죠.

또, 오디오 역시 갖고 있을테고 이 또한 bitrate에 따라 96kb와 192kb로 세분화 시킬 수 있습니다.
이 외에 또 다른 데이터들 역시 갖고 있겠죠?

모든 데이터들을 총 집합시켜 한 화면에서 보자면 아래와 같을겁니다.
앱 하나에 이렇게 많은 데이터들이 있는데 모두 설치시키는것 보단 각 디바이스 환경에 맞게 설치하는게 효율적이겠죠?

그래서 나온게 슬라이싱(Slicing) 입니다.
디바이스에 맞는 리소스들과 코드들을 골라서 앱스토어에서 슬라이싱을 하고, 별도의 IPA를 만들어 전달합니다.
이 과정을 위에서는 변형(variants)을 생성하고 전달한다고 표현한것이죠.

여기까지만 하더라도 좋지만, 우리는 더 나아질 수 있을까요?
실행가능한 코드들과 기본 인터페이스 및 아트워크는 매번 필요하지만
어느것들은 매번 필요하지 않을 수도 있습니다.

예를들어, 나는 현재 1레벨 맵을 진행하고 있는데 4레벨, 5레벨 맵이 당장 필요할까요?
맨 처음에 진행 했던 튜토리얼이 이후로도 계속 필요할까요?

그렇다면 이것들을 어떻게 관리하면 될까요?




🌟 주문형 리소스(On-Demand Resources)

위에서 언급한것들을 해결하는것이 바로 주문형 리소스(ODR) 이라고 합니다.
말 그대로 필요할때 주문해서 가져와 사용하는 동적인 방식인거죠.

ODR은 앱스토어에 IPA와 별도로 저장되었다가 필요할때마다 더 많은 컨텐츠를 가져오도록 되어 있다고 합니다.
받은 데이터는 App Bundle이나 iCloud에 저장되지 않으며 "메모리"에 저장된다고 합니다.
정확하게 시스템에서 관리하는 메모리에 저장되고, 이 메모리는 다양한 앱에서 발생하는 ODR을 캐싱하는 역할을 합니다.

앱 안에 이런 데이터 및 리소스들이 들어있다고 가정해봅시다.

아래 사진을 앱 스토어가 슬라이싱을 끝낸 후의 ipa의 모습이라고 가정하고
shared는 매번 필요한 코드 및 아트워크들이고 나머지는 각 레벨의 던전들에 필요한 리소스라고 생각해봅시다.

ODR을 적용시키고 나면 매번 필요한 부분만 왼쪽으로 분리하여 ipa를 생성하여 기기에 갖고있도록 합니다.
그리고 오른쪽 영역은 앱 스토어가 갖고 있습니다.

위에서 말 한대로 우리는 당장 레벨1의 던전만 필요하고 나머지 레벨의 데이터 및 리소스들은 필요가 없습니다.
그러므로 레벨1에 대한 리소스만 앱스토어에 요청해봅시다. 그리고 이어서 레벨2, 레벨3에 대한 요청을 해봅시다.

그럼 차례 차례 해당 레벨에 대한 리소스들이 들어오게 됩니다.
그런데 3개를 요청했더니 메모리가 가득 차게 되었네요? 이 상태에서 레벨4, 레벨5를 요청하면 어떻게 될까요?

맨 먼저 들어왔던 레벨1, 레벨2의 리소스를 지우고 각각 레벨4, 레벨5를 메모리에 할당합니다.
이런 방식을 LRU(Least Recently Used) 라고 합니다. 가장 오랫동안 참조되지 않은 부분을 교체시키는 거죠.

만약 사용자가 오랫동안 앱을 사용하지 않고, 다른 앱에서 ODR을 요청하게 되면 해당 리소스들을 비워버리고 다른 앱의 리소스를 할당하는데 사용하게 됩니다. 그리고 앱을 다시 구동 시켰을때 로드하는 방식으로 동작하고 있죠.

🔥 ODR을 정리하자면..

  • Assets은 Xcode에 의해 만들어진다.
  • 실행 불가능한 Assets을 포함할 수 있다.
  • 앱스토어에서 호스팅함.
  • 필요할 때 다운로드하고
  • 필요 없을 때 도로 회수해감.
  • 디바이스에 맞게 최적화 됨.

🔥 ODR 장점

  • 스토리지 용량이 적은 디바이스에 대응이 가능하다.
  • 다운로드 시간 단축.
  • OTA 사이즈 제한에 적용하기 더 쉽다.
    (Cellular에서 다운 받을 때 200MB의 제한이 있었다.)
  • 성능 저하 없이 더 많은 유형의 디바이스 지원 가능.
  • 이전에는 맞추지 못했던 기능 추가 가능.




🌟 비트코드 (BitCode)

마지막은 비트코드 입니다.

그럼 비트코드는 뭔가요?
"아직 기계코드도 아니고 소스코드도 아닌 중간단계 코드(intermediate code)" 입니다.

그럼 중간단계 코드는 왜 사용할까요?
예시를 통해 이해를 해봅시다.

만약 비트코드를 안쓴 상태에서 앱을 64-bit에 맞게 컴파일 했는데, 추후에 새로운 아키텍쳐 arm64가 나왔다고 생각 해봅시다.
그럼 arm64를 사용하는 디바이스에선 해당 앱을 구동할 수 없으니 앱을 다시 arm64에 맞게 컴파일해서 올려야겠죠?

이런 번거로움을 막기 위해 중간코드를 사용합니다. 앱스토어에 개발자가 모든 환경의 바이너리가 아닌 비트코드를 제공해두면 애플 서버에서는 디바이스에 맞는 아키텍쳐에 맞게 비트코드를 컴파일한 뒤에 다운로드 될 수 있도록 제공합니다.

또, 비트코드를 사용하지 않으면 모든 환경에 대한 바이너리를 생성하여 하나의 파일로 합쳐 제공해야 하는데 이러면 당연히 파일 크기가 커지겠죠? 이것을 fat binary 라고 합니다.

하지만 비트코드를 사용하게 되면 디바이스의 아키텍쳐와 관련된 최적화만 제공하기 때문에 앱의 용량도 줄어든다고 합니다. 이러한 이점을 활용하여 App Thinning, App Slicing에 기여한다고 하네요.

iOS앱의 경우엔 비트코드가 default로 사용되고 있지만 Optional이기도 합니다. 하지만 watchOS에서는 필수 입니다.

🔥 LLVM (Low Level Virtual Machine)

위에서 언급한 내용들도 중요하지만, 비트코드의 핵심은 LLVM이라고 합니다.
LLVM은 내가 작성한 소스코드를 중간코드 혹은 기계코드로 컴파일 하는데 사용하는 컴파일러 라이브러리 입니다.

보통 컴파일러는 전단부(front-end)후단부(back-end)로 나뉘는데, 전단부는 소스코드를 분석하여 중간코드를 생성하는 작업을 하는 부분이고 후단부는 전단부에서 생성한 중간코드를 기계코드로 번역하는 부분입니다.

이것이 비트코드의 핵심인데, 위에서 앱 개발자가 비트코드 단계까지만 생성하여 앱스토어에 업로드 해두면 해당 비트코드를 가지고 기계코드로 번역하여 제공한다고 했죠? 이게 바로 컴파일러의 구조를 활용한 최적화 입니다.

앱 스토어에 올릴 때 후단부까지 컴파일을 진행하지 않고 전단부에서 비트코드를 생성한 뒤에 그 상태로 업로드 하면 앱 스토어 서버에서 유저가 다운로드를 요청하면 디바이스의 아키텍쳐에 맞게 후단부 작업을 진행하여 제공하게 됩니다.

즉, 새로운 아키텍쳐가 나올 때마다 애플은 그냥 해당 아키텍쳐를 지원하도록 후단부에 추가 하고 새로운 아키텍쳐로 컴파일 하는 방법을 비트코드에 표시하면 되는것이죠.






Reference

profile
iOS Developer 💻

0개의 댓글