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를 자주 이용함!