타이머
타이머는 애플리케이션에서 중요한 역할을 한다. React Native는 브라우저 타이머를 구현한다.
타이머
- setTimeout, clearTimeout
- setInterval, clearInterval
- setImmediate, clearImmediate
- requestAnimationFrame, cancelAnimationFrame
requestAnimationFrame(fn)
은 setTimeout(fn, 0)
과 다르다. requestAnimationFrame
은 모든 프레임이 처리된 후에 실행되지만, setTimeout
은 가능한 한 빠르게 실행된다(iPhone 5S에서는 초당 1000번 이상 실행될 수 있다).
setImmediate
는 현재 자바스크립트 실행 블록이 끝나는 시점, 즉 네이티브로 일괄 응답을 보내기 직전에 실행된다. setImmediate
콜백 내에서 setImmediate
를 다시 호출하면, 즉시 실행되며 네이티브로 되돌아가지 않는다.
Promise
구현은 비동기 처리를 위해 setImmediate
를 사용한다.
Android에서 디버깅할 때, 디버거와 디바이스의 시간이 차이가 나면 애니메이션, 이벤트 동작 등이 제대로 작동하지 않거나 결과가 정확하지 않을 수 있다. 이를 해결하려면 디버거 머신에서 adb shell "date `date +%m%d%H%M%Y.%S%3N`"
명령어를 실행한다. 실제 디바이스에서 사용하려면 루트 접근 권한이 필요하다.
InteractionManager
잘 만들어진 네이티브 앱이 부드럽게 느껴지는 이유 중 하나는 상호작용과 애니메이션 중에 부하가 큰 작업을 피하기 때문이다. React Native에서는 현재 단일 JS 실행 스레드라는 제약이 있지만, InteractionManager
를 사용해 상호작용이나 애니메이션이 끝난 후에 오래 걸리는 작업이 실행되도록 예약할 수 있다.
애플리케이션은 다음과 같이 상호작용 이후에 실행될 작업을 예약할 수 있다:
InteractionManager.runAfterInteractions(() => {
// ...오래 걸리는 동기 작업...
});
이를 다른 스케줄링 방법과 비교해 보면:
- requestAnimationFrame(): 시간에 따라 뷰를 애니메이션하는 코드에 적합하다.
- setImmediate/setTimeout/setInterval(): 나중에 코드를 실행하지만, 애니메이션을 지연시킬 수 있다.
- runAfterInteractions(): 활성 애니메이션을 지연시키지 않고 코드를 나중에 실행한다.
터치 처리 시스템은 하나 이상의 활성 터치를 '상호작용'으로 간주하고, 모든 터치가 끝나거나 취소될 때까지 runAfterInteractions()
콜백을 지연시킨다.
InteractionManager는 또한 애니메이션 시작 시 상호작용 '핸들'을 생성하고, 완료 시 이를 해제함으로써 애니메이션을 등록할 수 있게 해준다:
const handle = InteractionManager.createInteractionHandle();
// 애니메이션 실행... (`runAfterInteractions` 작업이 큐에 추가됨)
// 나중에, 애니메이션이 완료되면:
InteractionManager.clearInteractionHandle(handle);
// 모든 핸들이 해제되면 큐에 있는 작업이 실행됨