얼마 전에 Hermes 적용해봤다는 글엔진별 메모리 사용량 링크를 공유드렸는데요. 느낌상 좋아진 것 같다고만 생각하다가 정말 얼마나 개선됐는지 궁금해서 간단하게 측정해봤는데 이번에도 재미있게 봐주세요.

# 뭘 측정할 것인가?

Hermes는 자바스크립트 번들 파일을 빌드 타임에 Bytecode로 변환시킨 후 재사용해서 반복적인 파싱과 컴파일 단계를 제거해서 앱 초기 실행 속도를 개선한 안드로이드용 자바스크립트 엔진입니다.

사용자가 앱을 실행하고 초기화 작업이 끝나서 기본적은 렌더링이 완료되고 화면을 인지하는 시점을 TTI(Time To Interaction)로 정의하고 얼마나 개선되는지 확인해보겠습니다.

# 어떻게 측정할 것인가?

React Native는 내부적으로 초기화가 실행되는 단계마다 ReactMarker 이벤트를 남기고 있는데 이 정보를 이용하면 단계별로 소요된 시간을 측정할 수 있습니다.

<aside> 📖 성능 측정 관련해서 참고한 글

</aside>

  1. android/app/src/main/java/com/nparashuram 폴더에 PerfLogger.java 파일을 생성해주세요.

  2. MainApplication.java 에 PerfLogger를 초기화해주세요.

    import com.nparashuram.PerfLogger;
    
    public class MainApplication extends Application implements ReactApplication {
    	....
    	@Override
      public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
        new PerfLogger(getReactNativeHost()).initialize();
      }
    }
    
  3. 사용자가 앱을 사용할 수 있는 최초 시점에 보이는 View 중 하나에 nativeID 속성을 정의해주세요.

    <View nativeID="tti_complete">
      ....
    </View>
    

PerfLogger가 하는 일은

  1. 초기화 되는 시점에 최초 실행 시간을 저장
  2. React Native의 marker 이벤트가 발생할 때마다 배열에 이벤트명과 시간과 기타 정보를 포함해서 추가
  3. 뷰가 생성되는 것을 모니터링하다가 tti_complete 이름을 가진 뷰가 만들어지면 TTI_COMPLETE 이벤트명으로 배열 마지막에 추가
  4. 자바스크립트 영역의 global에 AXE_PERFLOGGER에 JSON 형식으로 결과 저장

AXE_PERFLOGGER에 저장되는 값은 아래와 같습니다. 이벤트명은 ReactMarkerConstants.java 에서 확인하실 수 있어요.

global.AXE_PERFLOGGER = {
	startTime: 1564470043144,
	data: [
		{
			time: 1564470043154,
			name: 'CREATE_REACT_CONTEXT_START',
			...
		},
		....,
		{
			time: 1564470045154,
			name: 'TTI_COMPLETE',
			...
		},
	]
}

TTI 시간은 아래처럼 구할 수 있죠.