1. 60fps는 어렵다
부드러운 화면을 만들기 전에 “1초에 60번, 16.67ms 안에 한 프레임을 끝내는 것”에서 시작한다.
1-1. Frame Rendering Cycle
JS가 3ms를 조금 넘는다고 항상 나쁜 건 아님!
Input → JS → Layout → Paint → commit → 여유
- 여유 공간이 있어야 다음 프레임을 실행시키기 좋다.
1-2. Jank가 생기는 순간
한 프레임이 늦어지는 과정
Frame1 → Frame2 → Frame3 → Frame4 이렇게 작동한다고 할 때, Frame3이 끊김이 생길 경우 Frame4에도 영향을 준다.
1-3. Old Architecture : Bridge 구조
기존에는 bridge를 걸쳐 대화를 하였다.
따라서 Bridge에서 Json을 직렬화 역직렬화 하는 과정에서 병목 현상이 일어나기 좋은 구조였다.
1-4. New Architecture
Old Architecture에서 병목 현상을 줄이는 방법이다.
- Bridge를 최대한 우회하고 필요한 곳은 직접 접근한다.
JSI + Fabric + TurboModules
JS와 Native가 더 직접적으로 상호작용한다.
- 직접 메모리 공유
- 동기 접근 가능
- 최신 React Native SDK의 핵심
1-5. JS Thread & UI Thread
JS Thread
- 비지니스 로직
- 상태 관리와 React fpsejfld
- API 호출과 데이터 가공
- 라우팅, Store 액션, 이벤트 헨들러, 비동기 처리
UI Thread
1-6. Shared value
JSI의 핵심
- React가 reredering 없이 값이 바뀌고, UI쪽 style worklet이 즉시 다시 계산된다는 점
1-7. Worklet 컴파일
- 빌드 시점에 UI 런타임에서 실행 가능한 형태로 전환
useAnimatedStyle, useAnimatedScrollHandler, Gesture
runOnUI & runOnJS
2. Reanimated API
2-1.
2-2. withTiming & withSpring
withTiming
항상 몇 ms 뒤에 끝난다가 보장
withSpring
끝나는 시간보다 “어떻게 수렴하는가”가 중요
2-3. Hook의 법칙과 damping / stiffness
- stiffness : 반응은 빠르지만 과하면 딱딱함
- damping : 크면 통통 튀는 움직임을 줄고 빨리 안정됨.
2-4. Easing Curve Theory
ease-in
천천히 시작해서 끝으로 갈수록 빨라짐
ease-out
빠르게 출발하고 끝에서 천천히 멈춤
ease-in-out
출발과 도착 모두 완만함
2-5. withSequence
순서가 있는 애니메이션을 만들 때 사용
2-6. Interpolate 원리
입력 범위를 다른 출력 범위로 바꿔 주는 매핑 도구
선형 보간
2-7. useAnimatedScrollHandler
스크롤 이벤트를 JS로 보내지 않고 UI Thread에서 바로 처리하는 것
3. Gesture Handler
- reanimated랑 같이 사용하면 더 완성된 앱을 만들기 좋다.
3-1. Touch event pipeline
하드웨어 → 운영체제 → GestureHandler → Recongnizer → Worklet 콜백
왜 중요한가?
충돌은 보통 Recongnizer 단계에서 발생함. activeOffset, Race, Simultaneous를 이해해야 함.
ex ) 사진을 확대한 상태에서 더블 클릭해서 좋아요 누르기. → 누가 먼저 활성화될지 기준
3-2. Gesture Recongnizer State Machine
3-3. 3가지 Gesture 합성 방식
- 어떤 기준으로 제스처들을 통제할지 사용자의 의도에 맞게 선택해야 한다.
Simultaneous
- 동시에 활성화
Race
- 먼저 활성화된 제스처가 승리
Exclusive
- 앞 제스처가 실패해당 뒤 제스처를 시도
3-4. Gesture 충돌 해소 전략
방향 분리
합성 방식
- Simultaneous
- Race
- Exclusive
예시로 판단하기
3-5. GestureHandlerRootView와 GestureDetector
GestureHandlerRootView
OS의 터치 이벤트를 Gesture Handler가 먼저 받을 수 있게 루트에서 감싸는 역할
GestureDetector
특정 뷰 여역에 어떤 gesture를 붙일지 연결해줌.
3-6. Pan Gesture
translationX
제스처 시작점을 기준으로 얼마나 이동했는가?
velocityX
현재 속도
threshold
삭제로 불치 복귀로 볼지의 기준
activeOffsetX
가로로 충분히 움직였을 때만 Pan 활성화
3-7. Pinch gesture의 saved Scale 패턴
이전 배율을 저장
3-8. LongPress
onEnd
- ACTIVE → END로 정상 종료될 때만 호출
onFinalize
- END / FAILED / CANCELLED 모두 정리
Tip
일반적으로 onFinalize를 자주 이용함!