점진적으로 최적화 채택

기본적으로 R8은 성능과 크기를 개선하기 위해 많은 최적화를 실행하지만, 최적화가 앱에 즉시 적용되지 않을 수 있습니다. 대규모 앱에서 R8을 사용 설정하거나 (또는 전체 모드를 사용 설정) 처음으로 사용 설정하는 경우 최적화를 점진적으로 도입해 보세요. 난독화를 일시적으로 사용 중지하고 앱의 모든 코드가 아닌 코드의 일부에 한 번에 R8을 사용 설정합니다. 로컬 개발 중에 이 점진적 접근 방식을 사용하는 것이 좋지만 내부 QA 테스트 중에 사용하거나 프로덕션에서 점진적으로 출시하는 데도 사용할 수 있습니다. 취하는 정확한 단계는 원하는 타임라인과 출시 전 테스트 범위에 대한 확신에 따라 다릅니다.

최적화 제한

R8은 코드 삭제, 코드 재작성, 리소스 삭제를 비롯한 다양한 유형의 최적화를 실행합니다. 다음은 최적화 유형에 대한 대략적인 설명입니다.

  • 코드 축소 (또는 트리 쉐이킹): 참조되지 않는 코드 삭제
  • 난독화 (또는 식별자 축소): 클래스 및 메서드의 이름을 줄입니다.
  • 최적화: 코드 재작성(예: 인라인 처리)

오류 발생 가능성을 줄이려면 이러한 최적화 중 일부만 사용 설정하여 시작할 수 있습니다.

트리 셰이킹만 사용 설정

코드 축소(트리 쉐이킹이라고도 함)는 참조되지 않는 것으로 보이는 코드를 삭제합니다. 가장 간단한 방법이므로 트리 셰이킹만으로 시작하는 것이 좋습니다.

트리 셰이킹만 사용 설정하려면 proguard-rules.pro 파일에 다음을 추가하여 다른 유형의 최적화를 사용 중지합니다. 난독화를 사용 중지하는 것이 중요합니다. 이렇게 하면 스택 트레이스를 훨씬 쉽게 읽을 수 있기 때문입니다.

-dontobfuscate // Use temporarily to turn off identifier minification
-dontoptimize // Use temporarily to turn off optimization

결국 이 구성은 R8의 코드 최적화 기능을 대폭 제한하므로 출시해서는 안 되지만, 수정해야 할 문제가 있는 대규모 코드베이스에서 R8을 처음 채택할 때는 좋은 출발점이 됩니다.

호환성 모드 사용

기본적으로 R8은 전체 모드로 실행됩니다. 전체 모드를 사용하면 성능과 크기가 크게 개선되지만 축소를 처음 사용 설정할 때는 일시적으로 사용 중지하고 대신 호환성 모드를 사용할 수 있습니다.

호환성 모드를 사용하려면 gradle.properties 파일에서 다음 설정을 사용하세요.

android.enableR8.fullMode = false // Use temporarily to disable full mode

나머지 최적화 사용 설정

앱에서 트리 쉐이킹이 작동하는지 확인한 후 위의 설정을 삭제하여 난독화, 최적화, R8 전체 모드를 다시 사용 설정할 수 있습니다. 난독화하면 디버깅이 더 어려워질 수 있으므로 트리 쉐이킹 문제를 먼저 해결하는 것이 좋습니다.

스택 트레이스 가독화에 관한 자세한 내용은 원래 스택 트레이스 복구를 참고하세요.

최적화 범위 제한

완전히 최적화된 빌드는 모든 라이브러리와 패키지에서 모든 코드를 최적화하므로 처음 사용 설정할 때 R8과 관련된 문제가 발생하는 경우가 많습니다. 앱의 한 부분에서 최적화 문제가 발견되면 R8을 완전히 사용 중지하지 마세요. 그러지 않으면 다른 부분에서 이점을 누릴 수 없습니다. 대신 문제를 일으키는 앱 부분에서만 R8을 일시적으로 사용 중지하세요.

패키지 전체 keep 규칙 사용

앱의 일부에서 R8을 일시적으로 사용 중지하는 방법으로 패키지 전체의 유지 규칙을 사용하는 것이 좋습니다. 나중에 이러한 최적화 문제를 해결하려면 항상 다시 돌아와야 합니다. 이는 일반적으로 문제 영역을 해결하기 위한 임시 해결 방법입니다.

예를 들어 앱의 일부에서 Gson을 많이 사용하고 최적화 문제가 발생하는 경우 타겟팅된 유지 규칙을 더 추가하거나 codegen 솔루션으로 전환하는 것이 가장 좋습니다. 하지만 나머지 앱의 최적화를 차단 해제하려면 Gson 유형을 정의하는 코드를 전용 하위 패키지에 배치하고 다음과 같은 규칙을 proguard-rules.pro 파일에 추가하면 됩니다.

-keep class com.myapp.json.** { *; }

사용 중인 일부 라이브러리에 내부 구성요소에 대한 반사가 있는 경우 마찬가지로 전체 라이브러리에 keep 규칙을 추가할 수 있습니다. 보관할 적절한 패키지를 찾으려면 라이브러리의 코드 또는 JAR/AAR을 검사해야 합니다. 장기적으로 유지하는 것은 좋지 않지만 나머지 앱의 최적화를 차단 해제할 수 있습니다.

-keep class com.somelibrary.** { *; }

패키지 전체 유지 규칙 삭제

앱이 패키지 전체 keep 규칙으로 올바르게 작동하면 다시 돌아가서 타겟팅된 keep 규칙을 추가하거나 애초에 keep 규칙이 필요한 리플렉션 사용 또는 라이브러리를 삭제해야 합니다.

예를 들어 AndroidX에서는 관련 클래스만 유지하기 위해 특정 클래스를 확장하는 모든 규칙을 유지하는 것이 매우 일반적입니다. 일반적으로 리플렉션은 특정 추상 클래스를 확장하거나 특정 인터페이스를 구현하거나 특정 런타임 주석이 있는 클래스를 타겟팅해야 합니다. 이러한 각 방법은 완전히 최적화된 최종 앱에 패키지 전체의 유지 규칙이 필요하지 않도록 유지 규칙을 정의하는 데 지원되는 방법입니다.