React Native에서 모달 등장 시 미세한 jank 원인을 추적한 기록
개요 React Native + Tamagui Dialog로 만든 알림 모달이 등장할 때마다 미세한 jank가 발생했다. 처음엔 모달 컴포넌트 자체가 무겁다고 의심했지만, 진짜 범인은 모달이 뜨는 그 순간 같이 발사되는 5개의 네트워크 요청이었다. 이 글은 그 원인을
A tag-first restructuring of my frontend and React Native learning notes and retrospectives, curated on Velog (@diso592).
개요 React Native + Tamagui Dialog로 만든 알림 모달이 등장할 때마다 미세한 jank가 발생했다. 처음엔 모달 컴포넌트 자체가 무겁다고 의심했지만, 진짜 범인은 모달이 뜨는 그 순간 같이 발사되는 5개의 네트워크 요청이었다. 이 글은 그 원인을
React Native 가상화 리스트 성능 props 정리 — FlatList vs FlashList vs LegendList 긴 리스트의 성능 문제는 결국 "화면에 보이지 않는 아이템까지 다 그리느냐"의 싸움이다. 세 라이브러리 모두 가상화(virtualizatio
개요 최적화는 어디서 시간이 쓰이는지 분해하는 데서 시작한다. 콜드 스타트는 크게 다음 구간으로 나뉜다. 프로세스 생성 + 네이티브 초기화 — OS가 앱 프로세스를 띄우고 네이티브 런타임이 올라오는 구간이다. 앱이 직접 줄이기 가장 어렵다. JS 엔진 초기화 +
개요 물리적 iOS 기기에서 앱이 실행된 직후 Metro 번들러와의 연결이 끊어지는 현상은 기기가 Mac에서 실행 중인 Metro 서버(기본 포트 8081)와 통신하지 못할 때 발생생한다. 시뮬레이터와 달리 물리적 기기는 USB 연결만으로는 디버그 서버와 통신할 수
1. eslint-plugin-react-hooks개요 핵심 전제부터 짚는다. React Compiler는 위반을 만나면 빌드를 실패시키지 않고 해당 함수를 그대로 둔다. 즉 "skip"은 에러가 아니라 안전 후퇴(silent bailout)다. RC는 Rules o
개요 RC를 도입했을 때 수동 메모이제이션이 불필요해지는 라이브러리·기능들을 정리해보자. 결론부터 말하자면 본질은 모두 같다. RC가 인라인 객체·함수·배열을 표현식 단위로 자동 캐시하므로, 그 위에 손으로 깔던 useMemo / useCallback / React.m
1. React Compiler란? React Compiler(이하 RC)는 빌드 타임에 코드를 분석해 메모이제이션을 자동으로 삽입하는 컴파일러다. 지금까지 개발자가 손으로 깔던 React.memo / useMemo / useCallback을, 컴파일러가 데이터 흐름
1. 개요 React의 메모이제이션(React.memo, useMemo, useCallback)은 효과가 작거나 오히려 손해가 나는 경우에는 적용하지 않는 것이 정석이다. 비교 연산과 메모리 비용이 절약되는 렌더 비용을 초과할 수 있기 때문이다. 그렇다면 React
이제 android/fastlane/Fastfile이 실제로 어떤 일을 하는지 lane 단위로 뜯어본다. 앞 편에서 만든 keystore·Service Account·.env 토대 위에 드디어 진짜 빌드·업로드 코드를 얹는 단계다. 구조는 iOS 편과 거의 대칭이다.
개요 이번 편이 끝나면 다음 세 줄로 환경별 Play Store 트랙 업로드가 끝난다. 내부적으로는 각각 다음 명령을 호출한다. 이를 위해 다루는 내용은 다음과 같다. Android keystore(업로드 키) 생성과 안전한 보관 Play App Signing
이제 ios/fastlane/Fastfile이 실제로 어떤 일을 자동화하는지, lane 단위로 뜯어본다. 앞 편에서 만든 서명·환경 토대(match, .env, 인증서) 위에 드디어 진짜 빌드·업로드 코드를 얹는 단계다. 아래에서 다루는 Fastfile은 3가지 환경
이번 편이 끝나면 아래 세 줄로 환경별 TestFlight 배포가 되는 상태를 향해 간다. (세 줄이 실제로 완성되는 건 실제 빌드·업로드 lane을 붙이는 다음 편이고, 이번 편은 그걸 위한 서명·환경 토대를 만든다.) 지금은 무슨 뜻인지 몰라도 되고, "이걸 만드는
개요 - 왜 Fastlane인가 React Native CLI로 앱을 만들다 보면 "코드는 다 됐는데 스토어에 올리는 게 더 오래 걸린다"는 순간이 온다. iOS는 Xcode에서 Archive → Distribute → App Store Connect 업로드, And
개요 > 이 글을 읽기 전에 알아두면 좋은 관점 하나. RN 개발을 하다 보면 npm run android, npm run ios 정도로 앱이 폰에 뜬다. 하지만 그건 내 컴퓨터에 꽂힌 디바이스나 시뮬레이터에 개발용으로 설치하는 것이고, 스토어에 올려서 남에게 배포하
[legend-list] List height is 0 경고 정리 > WARN [legend-list] List height is 0. You may need to set a style or flex: for the list, because children are
React Native CLI 프로젝트에서 "앱 이름"은 하나가 아니다. 홈 화면에 보이는 이름, 번들 내부 식별용 이름, JS에 등록된 컴포넌트 이름이 각각 따로 존재한다. 이 셋을 구분하지 못하면 이름을 바꿔도 반영되지 않거나 앱이 아예 실행되지 않는다.
개요 Upgrade Helper는 두 React Native 버전 사이에 변경된 파일을 diff 형태로 보여주는 웹 도구이다. 공식 주소는 다음과 같다. React Native 프로젝트는 본질적으로 Android 프로젝트 + iOS 프로젝트 + JavaScript(
개요 React Native CLI 프로젝트에서 reanimated와 worklets 라이브러리를 최신 버전으로 업그레이드한 뒤, iOS 빌드가 특정 지점에서 멈춰버리는 현상이 발생했다. 빌드 로그가 한참을 멈춰 있어 "무한 대기"처럼 보이는 상황. 원인을 추적해보니
1. URL 스킴이란 무엇인가 URL의 맨 앞 scheme:// 부분이 스킴(scheme) 이다. 어떤 프로토콜/대상으로 이 URL을 처리할지 가리키는 이름표다. https는 브라우저가 처리하도록 OS에 예약된 표준 스킴이고, example:// 같은 임의의 이름은
개요 위치 기반 기능은 에뮬레이터/시뮬레이터만으로는 충분히 검증하기 어렵다. 실제 GPS 칩, 센서 퓨전, 배터리 상태, OS의 위치 권한 동작이 시뮬레이터와 다르기 때문이다. 그렇다고 매번 실제로 이동하면서 테스트할 수는 없다. 그래서 실기기에 가상(mock) GP
개요 - "온라인은 예외 상태다" 모바일에서 네트워크는 항상 불안정하다고 전제하고 설계한다. 안정적으로 고정된 위치에서 연결이 이루어지는 PC와 달리, 스마트폰은 지하철·엘리베이터·터널·해외 로밍·약한 와이파이와 연결된 케이스는 흔히 일어나는 일상이다. 때문에 앱개발
개요 React Native 앱에는 JS 캐시(TanStack Query) 외에 OS 레벨 HTTP 캐시가 추가로 존재한다. 이 글은 그 레이어가 왜 생기는지, 어떤 문제를 일으키는지, 그리고 실무에서 보통 어떻게 대응하는지를 정리한다. 1. 웹 vs 앱: HTTP
개요 RN에서 이미지 캐싱을 다루다 보면 "디코딩"이라는 단어를 계속 만나게 된다. "메모리 캐시를 비우면 다시 디코딩해서 깜빡인다", "큰 이미지 여러 장을 동시에 디코딩하면 프레임이 튄다" 같은 문장들이다. 이 디코딩이 대체 무슨 작업이고, 왜 비용이 크며, 왜
개요 react native 에서 안드로이드는 빌드할 때, dev 든 release든 매우 느린 시간을 거친다. ios는 비교적 android보다 빠른 것 같은데, 왜 유독 android의 빌드 속도는 느린걸까? ios처럼 빠르게 할 수 없는 것일까? 이에 대해 살펴보
개요 containerLayoutState는 @gorhom/bottom-sheet 바텀시트 컨테이너의 레이아웃 정보를 담는 prop이다. 시트가 어느 높이까지 펼쳐질 수 있는지, 화면 어디에 얹혀 있는지를 계산하는 기준값이다. 기존에 각각 존재하던 containe
개요 onTextLayout은 React Native `` 컴포넌트의 prop이다. 텍스트가 화면에 실제로 레이아웃(배치)될 때마다 호출되며, 각 줄(line) 단위의 위치·크기 정보를 콜백으로 전달한다. JS 측에서 미리 알 수 없는 "텍스트가 몇 줄로 나뉘는가",
개요 라이브러리나 RN 버전, 빌드 도구 업그레이드를 언제 어느 타이밍에 진행하는게 가장 Best 일지 의문을 품었다. 프로젝트를 장기간 몇개월 ~ n년 진행하면 deprecated 된 기능들이 나올텐데, 그러면 어떠한 기준을 가지고 패키지들의 버전을 점검하는지가 궁
개요 iOS에서는 hitSlop을 키우면 그대로 터치 영역이 늘어나지만, Android에서는 부모 뷰의 경계에 막혀 무시되는 경우가 있다. 이 문서는 그 원인과 우리 코드베이스에서 채택한 해결 패턴을 정리해보자. ios 와 android의 hit test 처리 방식
개요 앱이 종료될 때는 한마디로 요약하면, 앱 프로세스 종료 → JS 런타임 종료 → 힙 삭제가 일어난다. 이 과정이 실제로 어떻게 일어나는지, 그리고 이걸 실무에서 어떻게 활용하는지 알아보자. 1.핵심 전제 : "종료는 예고 없이 온다" 먼저 가장 중요한 사실부
React Native에서 비대칭 borderRadius가 만드는 한 프레임 잔상 가로 스크롤 리스트의 필터 탭을 전환할 때, 화면 좌상단으로 작은 검은 박스가 한순간 사라지는 잔상이 보였다. 원인은 리스트 라이브러리가 아니라, 한 박스에 비대칭 borderRadiu
ListEmptyComponent vs 삼항연산자 — 무엇이 다른가 FlashList, LegendList(그리고 RN 기본 FlatList)에는 ListEmptyComponent라는 prop이 있다. data가 비어 있을 때 자동으로 이 컴포넌트를 렌더링해준다. 그
React Navigation 정적 API의 Deep Linking > 대상: React Native CLI + @react-navigation/native-stack (v7, Static API) > 범위: linking이 무엇인지부터, 정적 API에서 그것이 어떻
React Native 메모리 누수 & OOM 크래시 대응 > 대상: React Native CLI + New Architecture(Hermes, JSI, Fabric) 환경 > 목표: 메모리가 새는 지점을 막고, 저사양 단말에서 OOM(Out Of Memory)
개요 React Native CLI 프로젝트를 개발하다 보면 bundle install, bundle exec pod install, bundle exec fastlane ios beta 같은 명령을 매일 마주친다. JS 개발자에게는 낯선 Ruby 생태계지만, 실은
개요 useMutation을 쓰다 보면 onSuccess, onError, onSettled 같은 콜백의 인자가 헷갈리는 순간이 온다. "이 variables는 어디서 온 거지?", "context는 또 뭐지?", "mutationFn은 인자를 안 받는데 onSucc
개요 ` 만 써도 대부분의 버튼은 동작한다. 하지만 햅틱 피드백을 정확히 누르는 순간에 주고 싶거나, 길게 누르기와 짧게 누르기를 구분하거나, 드래그 중 손가락이 버튼 밖으로 살짝 빠져나가도 클릭을 유지하고 싶다면 onPress` 하나로는 부족하다. React Na
@gorhom/bottom-sheet props의 참조 안정성 @gorhom/bottom-sheet의 onChange, backdropComponent, snapPoints 같은 props에 메모이제이션된 값/함수를 넘겨야 하는 이유와, 그렇지 않았을 경우 발생하는
React Native CLI 환경에서 프로덕션 레벨의 앱을 준비할 때, 사용자가 앱을 쓰다 갑자기 앱이 픽 꺼져버리는(Crash) 현상만큼 서비스에 치명적인 것은 없다. 하지만 안타깝게도 모든 상황 100% 에러가 없이 완벽하게 작동이 되진 않는다. 어떠한 이유로든
개요 내 컴퓨터(Mac/Windows)의 **React Native 개발 환경이 정상적으로 갖춰져 있는지 진단하고, 문제점(에러)을 찾아주는 기능이 있다. 바로 react-native doctor 이다. React Native CLI에 내장된 개발 환경 진단 도구이다
개요 Reanimated에서 useAnimatedReaction, useDerivedValue, useAnimatedStyle 같은 훅이나 외부 라이브러리(@gorhom/bottom-sheet 등) 내부의 reaction이 불필요하게 재평가·재등록될 때, 왜 그것이
Reanimated 는 애니메이션 로직을 UI 스레드에서 실행시켜 60fps 의 부드러운 동작을 보장한다. 하지만 라이브러리를 잘못 사용하면 오히려 성능이 떨어지거나, 원인을 찾기 어려운 버그를 만나게 된다. 이번 글에서는 공식 문서와 실무 경험을 기반으로 Reanim
2편에서 Reanimated가 UI 스레드에서 어떻게 동작하는지, 3편에서 제스처를 어떻게 UI 스레드와 동기화하는지 살펴봤다. 이번 글에서는 마지막 퍼즐 — React의 렌더링 라이프사이클과 Yoga(레이아웃 엔진)의 계산 결과를 중간에서 가로채어 애니메이션을 주입하
2편에서 useSharedValue와 useAnimatedStyle을 잠깐 다뤘지만, Reanimated는 그 외에도 다양한 훅을 제공한다. 이번 글에서는 실무에서 자주 쓰이는 훅들을 깊이 있게 정리한다. 각 훅이 언제 쓰이는지, 어떻게 동작하는지, 흔히 빠지는 함정은
이전 글에서 Reanimated가 어떻게 JS 스레드를 거치지 않고 UI 스레드에서 애니메이션을 실행하는지 살펴봤다. 이번 글에서는 그 마지막 퍼즐 조각인 사용자 상호작용(Interaction) — 즉, 손가락의 움직임을 UI 스레드에서 어떻게 처리하는지 다룬다. 모
개요 이전 글에서 React Native 애니메이션의 기본 개념과 JS 스레드/UI 스레드 구조를 살펴봤다. 이번 글에서는 Reanimated가 어떻게 JS 스레드를 거치지 않고 60fps 애니메이션을 실현하는지, 그 내부 동작 원리와 실무에서 반드시 알아야 할 패턴
개요 React Native에서 가장 까다로운 작업 중 하나를 꼽으라면 단연 애니메이션이다. 그것도 그냥 애니메이션이 아닌, 부드럽고 끊김 없이 자연스러운 60fps(혹은 120fps) 애니메이션을 구현하는 것이다. 이를 위해 사실상 표준처럼 사용되는 라이브러리, re
react-native-version-check는 사용자가 설치한 앱의 버전과 앱스토어/플레이스토어에 올라와 있는 최신 버전을 비교해서 "업데이트가 필요한지" 알려주는 라이브러리다. 주로 "강제 업데이트(Force Update)" 기능을 구현할 때 필수적으로 사용된다
개요 React Native의 새로운 아키텍처(New Architecture)와 최근 생태계에서 고성능 기술로 주목받는 Nitro Modules에 대해 알아보자. 2026년 현재, 이 두 기술은 React Native의 고질적인 성능 한계를 돌파하는 핵심적인 개념이다.
Navigation이란? 앱에서 사용자가 여러 화면(페이지) 사이를 이동하고 탐색할 수 있게 해주는 시스템을 의미한다. 웹에서는 `` 태그나 URL 변경으로 페이지 이동을 하지만, 모바일 앱은 화면이 하나씩 쌓이거나 탭으로 전환되는 방식이 일반적이기 때문에 네비게이션
개념 RN(React Native)에서 이미지 파일 이름에 @2x, @3x 같은 suffix(접미사)가 붙어 있는 건 화면 밀도(screen density / pixel ratio) 에 따라 최적화된 이미지를 자동으로 선택하기 위한 iOS 스타일의 asset scali
Velog GraphQL → deployment pipeline → RSC static rendering
Velog @diso592
GraphQL API
scripts/fetch-velog.ts
try/catch + exit(0)
src/data/velog-posts.json
committed seed
Next.js 16 RSC
utilFetchVelogArchive
/{locale}/writings
static HTML
A GitHub Actions cron polls the velog RSS and triggers a deploy webhook when a new post is detected.
SOURCE
velog.io/@diso592 posts + tags
FETCH
GraphQL cursor pagination on deploy
SEED
committed seed, previous JSON retained on failure
RENDER
server fs load, RSC static rendering
OUTPUT
/{locale}/writings static HTML