점진적으로 최적화 채택

기본적으로 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을 일시적으로 사용 중지하세요.

패키지 전체 유지 규칙 사용

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

예를 들어 앱의 일부에서 Gson을 많이 사용하고 최적화 문제가 발생하는 경우 더 구체적인 유지 규칙을 추가하거나 코드 생성 솔루션으로 이동하는 것이 이상적인 해결책입니다. 하지만 앱의 나머지 부분을 최적화할 수 있도록 하려면 Gson 유형을 정의하는 코드를 전용 하위 패키지에 배치하고 proguard-rules.pro 파일에 다음과 같은 규칙을 추가하면 됩니다.

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

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

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

패키지 전체 유지 규칙 삭제

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

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

자체 코드베이스에 리플렉션이 있는 경우 패키지 전체 유지 규칙을 Jetpack Keep으로 바꿀 수 있습니다. 생성된 규칙은 조건부입니다. R8은 리플렉션 호출의 대상을 호출을 실행하는 코드도 유지하는 경우에만 유지합니다. 패키지를 이전하려면 Jetpack Keep 린트 검사를 사용하여 리플렉션 호출을 찾고 주석을 단 후 패키지 전체 규칙을 삭제합니다.