React · 2026-03-07

React Native 모바일 UI 최적화와 웹과의 차이

React Native에서 웹과 다른 렌더링·쓰레드 구조를 이해하고 레이아웃·리스트·애니메이션·이미지 최적화 원칙을 정리한 설명

작성일 : 2026-03-07 ㆍ 작성자 : 관리자
post
목차

개요

웹 개발 경험이 있는 상태에서 React Native로 옮겨오면 익숙한 패턴이 통하지 않는 부분이 있다. 핵심 차이를 이해하면 불필요한 성능 문제를 예방할 수 있다. 이 글은 웹과 다른 구조적 특징을 설명하고, 실무에서 바로 적용할 수 있는 최적화 원칙을 정리한다.

웹과 모바일 UI의 핵심 차이

렌더링 엔진과 레이아웃

웹은 브라우저의 DOM과 CSS엔진이 레이아웃을 처리한다. 반면 React Native는 네이티브 뷰 계층과 Yoga(플렉스 박스 엔진)를 사용한다. DOM 조작이나 CSS 리플로우와 달리, RN은 스타일 변경이 네이티브 레이어로 전달될 때 레이아웃 계산과 네이티브 업데이트 비용이 발생한다.

쓰레드 구조와 성능 병목

웹은 주로 메인 스레드에서 렌더링을 담당한다. RN은 JavaScript 스레드, 렌더 스레드(네이티브), 그리고 UI 스레드가 존재한다. 무거운 JS 연산이나 빈번한 레이아웃 변경은 JS-네이티브 통신을 늘려 jank(끊김)를 유발한다. 따라서 병목이 어디서 발생하는지 구분하는 것이 우선이다.

레이아웃 성능 최적화 전략

StyleSheet와 인라인 스타일

스타일 객체를 매 렌더마다 새로 생성하면 referential equality가 깨져 불필요한 재렌더가 발생한다. StyleSheet.create를 사용해 스타일을 정적으로 정의하고, 동적 스타일은 최소화한다. 또한 배열 합치기나 전개 연산으로 매번 새로운 객체를 만들지 않도록 주의한다.

컴포넌트 재렌더링 제어

불필요한 렌더 방지를 위해 PureComponent, React.memo, useCallback, useMemo를 적재적소에 사용한다. 하지만 과도한 메모이제이션도 오히려 복잡도를 높이므로 프로파일링을 통해 병목을 확인한 뒤 적용한다. props로 전달하는 콜백은 useCallback으로 묶고, 객체나 배열은 상위에서 재사용한다.

레이아웃 변경 최소화

레이아웃이 자주 변하면 네이티브에서 재계산 비용이 커진다. 애니메이션은 transform과 opacity를 우선 사용하고, 레이아웃을 바꾸는 애니메이션은 최소화한다. 또한 불필요한 뷰 중첩을 줄여 뷰 트리 깊이를 얕게 유지하면 측정과 그리기 비용을 낮출 수 있다.

리스트 성능(FlatList 중심)

스크롤 기반 리스트는 모바일에서 가장 빈번한 성능 이슈 발생 지점이다. 다음 설정을 활용해 리스트 성능을 개선한다.

  • keyExtractor로 안정적 키 제공
  • getItemLayout으로 항목 높이 미리 계산
  • initialNumToRender, maxToRenderPerBatch, windowSize 조절
  • removeClippedSubviews로 화면 밖 뷰 제거
  • renderItem을 메모이제이션하고 불필요한 래퍼 제거

아래는 기본적인 최적화 예시 코드다.

const renderItem = React.memo(({ item }) => {
  return <View><Text>{item.title}</Text></View>
});

<FlatList
  data={data}
  keyExtractor={item => item.id}
  renderItem={renderItem}
  initialNumToRender={10}
  maxToRenderPerBatch={10}
  windowSize={5}
  getItemLayout={(data, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index })}
  removeClippedSubviews
/>

애니메이션과 인터랙션

애니메이션은 가능하면 네이티브 드라이버를 사용한다. Animated의 useNativeDriver 옵션이나 Reanimated 같은 라이브러리를 활용하면 애니메이션이 JS 스레드에 의존하지 않아 부드럽게 동작한다. 터치와 스크롤 상호작용은 InteractionManager.runAfterInteractions으로 무거운 로직을 지연하는 것이 좋다.

이미지와 리소스 관리

이미지는 메모리 소비가 크다. 명시적 width/height 지정, 적절한 해상도 제공, 캐싱 라이브러리 사용을 권장한다. react-native-fast-image 같은 라이브러리는 네이티브 캐시를 활용해 로딩 비용을 줄인다. 가능한 경우 이미지 압축과 서빙 전략도 검토한다.

측정과 프로파일링

문제 해결은 측정에서 시작한다. Flipper, React DevTools, Performance Monitor, 그리고 Android Profiler/iOS Instruments를 사용해 JS 스레드와 UI 스레드의 사용률을 확인한다. console.log를 남발하면 성능을 악화시킬 수 있으므로 프로파일링 시에도 로그 사용을 줄인다.

결론

웹 개발과 다른 RN의 구조를 이해하면 훨씬 효율적으로 UI를 최적화할 수 있다. 핵심은 렌더링 경로를 이해하고, 재렌더링과 레이아웃 변경을 줄이며, 리스트와 애니메이션을 네이티브 친화적으로 다루는 것이다. 프로파일링을 통해 병목을 찾아 위에서 제시한 원칙을 적용하면 실사용 환경에서 체감 성능 개선을 얻을 수 있다.

react native 성능 최적화 리액트 네이티브 레이아웃 성능 react native ui best practice react native mobile ui 최적화 flatlist 최적화 이미지 최적화 애니메이션 최적화