기본 콘텐츠로 건너뛰기

라벨이 렌더링인 게시물 표시

React 동시성 이해하기: 입력은 즉시 반응하고 무거운 렌더링은 뒤로 미루는 법

React 동시성 이해하기: 입력은 즉시 반응하고 무거운 렌더링은 뒤로 미루는 법 빠른 답 현재 기준으로는 Concurrent Mode 라는 전역 모드를 켜는 방식보다, createRoot 기반의 동시 렌더링과 transition API를 필요한 업데이트에 적용하는 방식으로 이해하는 편이 정확합니다. 입력창 값처럼 즉시 반영되어야 하는 상태는 transition 으로 감싸지 않고, 그 입력에 따라 바뀌는 무거운 결과 영역만 낮은 우선순위로 미룹니다. 상태 업데이트를 직접 호출하는 위치라면 useTransition 또는 startTransition 을, 이미 전달받은 값의 화면 반영만 늦추고 싶다면 useDeferredValue 를 고려합니다. 동시성 API는 느린 계산을 빠르게 만드는 도구가 아니라, 사용자가 먼저 체감하는 렌더링이 막히지 않도록 우선순위를 나누는 도구입니다. 목차 시간 흐름으로 이해하기 흐름으로 보기 Concurrent Mode라는 표현이 헷갈리는 이유 설정 기준 잡기 데이터 흐름과 상태 소유권 useTransition과 startTransition을 쓰는 위치 useDeferredValue가 어울리는 경우 흔한 안티패턴 현재 기준의 마이그레이션 포인트 시간 흐름으로 이해하기 검색창에 글자를 입력하고 그 결과로 큰 목록이 다시 렌더링되는 상황을 기준으로 보면 React 동시성은 다음 흐름으로 동작합니다. 입력 발생 사용자가 검색어를 입력합니다. → 긴급 업데이트 입력창의 text 상태는 즉시 반영됩니다. → 전환 예약 결과 목록을 바꾸는 query 업데이트는 낮은 우선순위로 표시됩니다. → 렌더링 조정 결과 렌더링 중 새 입력이 들어오면 React가 기존 작업을 중단하거나 최신 값 기준으로 다시 시작할 수 있습니다. → 화면 커밋 렌더링이 완료된 결과만 실제 DOM에 반영됩니다. 여기서 중요한 구분은 입력 상태와 결과 상태를 같은 속도의 일로 보지 않는 것입니다. 사용자는 키를 눌렀을 때 글자가 바로 찍히는지를 먼저 ...

React useEffect는 언제 실행될까: 렌더링 이후 실행 흐름과 cleanup 순서

React useEffect는 언제 실행될까: 렌더링 이후 실행 흐름과 cleanup 순서 빠른 답 useEffect 는 렌더링 중이 아니라 렌더링 결과가 커밋된 뒤 실행된다. 의존성 값이 바뀌면 새 effect 본문이 실행되기 전에 이전 cleanup이 먼저 실행된다. 빈 배열은 프로덕션에서 한 번 setup되는 패턴이지만, 개발 환경 StrictMode 에서는 점검을 위해 setup과 cleanup이 한 번 더 실행될 수 있다. DOM 측정이나 화면 반영 전 동기 보정이 필요하면 useEffect 보다 useLayoutEffect 가 맞는지 확인해야 한다. 목차 시간 흐름으로 이해하기 흐름으로 보기 데이터 흐름과 상태 소유권 생명주기보다 외부 시스템 동기화로 보기 effect 실행과 cleanup 순서 의존성 배열은 실행 횟수가 아니라 반응 범위다 API 요청과 타이머에서의 cleanup Strict Mode 로그가 두 번 보일 때 useLayoutEffect와 화면 반영 전 작업 흔한 안티패턴 정리 시간 흐름으로 이해하기 렌더링 시작 props와 state로 다음 UI를 계산한다. → DOM 반영 계산된 결과가 커밋되어 실제 DOM에 반영된다. → 화면 갱신 브라우저가 변경된 화면을 그릴 수 있다. → effect 실행 현재 렌더의 값으로 setup 함수가 실행된다. → 의존성 변경 이전 cleanup이 먼저 실행되고 새 setup이 이어진다. useEffect 를 “마운트, 업데이트, 언마운트에 호출되는 함수”로만 외우면 cleanup이 왜 업데이트 때도 실행되는지 헷갈리기 쉽다. 더 정확히는 특정 렌더의 props와 state에 맞춰 외부 시스템을 연결하고, 다음 연결이 필요해지면 이전 연결을 정리하는 흐름으로 보는 편이 이해하기 쉽다. 흐름으로 보기 흐름 다이어그램 이 순서에서 effect는 렌더링을 막고 값을 계산하는 장소가 아니다. 렌더링에 필요한 값은 컴포넌트 함수 안에서 계산하고, API 요청, 이벤트 구독, 타이머, ...

React에서 useEffect와 useLayoutEffect, 언제 무엇을 써야 할까

React에서 useEffect와 useLayoutEffect, 언제 무엇을 써야 할까 빠른 답 기본 선택은 useEffect다. 네트워크 요청, 구독, 이벤트 등록처럼 화면 표시를 막을 이유가 없는 작업에 맞다. useLayoutEffect는 DOM 크기 측정이나 위치 보정처럼 화면이 그려지기 전에 끝나야 하는 작업에만 좁게 쓴다. useLayoutEffect는 브라우저 페인트를 막는 동기 작업이므로 무거우면 첫 화면 표시가 느려진다. React 18 개발 모드에서는 Strict Mode 때문에 Effect가 두 번 실행된 것처럼 보일 수 있어 타이밍 로그를 해석할 때 주의해야 한다. 현재 초안의 구조는 이미 잡혀 있어서, React 공식 문서와 MDN 기준으로 실행 시점 표현만 다시 확인한 뒤 발행용 문장으로 정리하겠습니다. 비교 섹션과 시간축 섹션은 초반에 더 압축하고, 오래된 설명으로 보일 수 있는 부분은 현재 기준 용어로 바로잡겠습니다.공식 문서 기준선은 반영했습니다. 현재 React 문서는 react.dev 의 최신 메이저인 React 19.2 기준이고, 오래된 글에서 자주 보이는 “항상 페인트 후”, “DOM 업데이트 직전” 같은 표현은 지금 문서의 설명과 어긋나는 부분이 있어 그 차이를 본문에 녹여 정리하겠습니다.# React에서 useEffect와 useLayoutEffect, 언제 무엇을 써야 할까 목차 한눈에 비교 시간 흐름으로 이해하기 왜 둘 다 렌더 후처럼 보일까 어떤 작업에 무엇을 써야 하나 깜빡임이 생기는 예제와 해결 방식 React 19.2 기준으로 다시 볼 점 SSR과 하이드레이션에서의 처리 성능과 DevTools에서 확인할 지점 한눈에 비교 실행 시점 useLayoutEffect 는 DOM 커밋 직후, 브라우저 리페인트 전에 실행된다. useEffect 는 대체로 페인트 뒤에 실행된다. 브라우저 영향 useLayoutEffect 는 현재 프레임의 표시를 막을 수 있다. useEffect 는 이미 그려진 화면 뒤...

React render phase와 commit phase, 리렌더링이 DOM에 반영되기까지

React render phase와 commit phase, 리렌더링이 DOM에 반영되기까지 빠른 답 render phase는 무엇이 바뀌어야 하는지 계산하는 단계라서 다시 실행되거나 중단될 수 있습니다. commit phase는 계산 결과를 실제 DOM에 반영하는 단계라서 짧고 일관되게 끝나는 것이 중요합니다. DOM 접근, 측정, 외부 부수효과는 render가 아니라 commit 이후 훅에서 처리해야 안전합니다. React 18 이후에는 render가 곧바로 화면 반영으로 이어진다고 보면 동작을 잘못 이해하기 쉽습니다. 목차 한눈에 비교 흐름으로 보기 왜 render phase와 commit phase를 자주 헷갈릴까 상태 변경부터 화면 반영까지 따라가기 실수를 빨리 잡는 설정 render에 둘 코드와 commit 이후에 둘 코드 로그로 보는 실행 순서 React 19.2 기준에서 달라진 설명 흔한 안티패턴과 디버깅 체크포인트 한눈에 비교 render phase : 컴포넌트를 호출해 다음 UI 스냅샷을 계산하는 단계입니다. 같은 입력이면 같은 출력이 나와야 하는 순수 계산이어야 합니다. commit phase : render 결과를 실제 DOM에 반영하는 단계입니다. ref 연결, DOM mutation, effect 실행 준비가 여기서 이어집니다. useLayoutEffect : commit 직후, 브라우저가 그리기 전에 실행됩니다. DOM 크기 측정이나 위치 보정처럼 paint 전에 끝나야 하는 작업에 맞습니다. useEffect : 외부 시스템과 동기화하는 용도입니다. 보통은 paint 뒤에 실행되지만, 사용자 상호작용으로 시작된 업데이트에서는 paint 전에 관찰될 수도 있습니다. 실무 기준으로는 파생값 계산은 render, DOM 측정은 useLayoutEffect , 네트워크·구독·타이머·로그 수집은 useEffect 로 나누면 거의 틀리지 않습니다. 흐름으로 보기 React 공식 문서는 이 과정을 trigger ...

리액트 성능 최적화, 무작정 memo 쓰기 전에 먼저 봐야 할 기준들

리액트 성능 최적화, 무작정 memo 쓰기 전에 먼저 봐야 할 기준들 빠른 답 느린 원인을 확인하기 전에는 memo부터 늘리지 말고 React DevTools Profiler로 병목을 먼저 찾습니다. 상태를 너무 상위에 두면 하위 전체가 자주 리렌더링되므로, 상태 소유권을 필요한 범위로 최대한 좁힙니다. useMemo와 useCallback은 비용이 큰 계산이나 참조 안정성이 실제로 필요한 경우에만 적용합니다. 초기 로딩이 느리다면 라우트 단위 코드 스플리팅부터 검토하는 편이 체감 성능에 더 직접적입니다. 목차 리액트 앱은 왜 느려질까 성능 최적화의 첫 단계: 상태 소유권 좁히기 React.memo, useMemo, useCallback은 무엇이 다를까 초기 로딩이 느리다면 코드 스플리팅부터 보기 Profiler로 먼저 확인할 것 흔한 안티패턴과 디버깅 포인트 무엇부터 적용하면 좋을까 리액트 앱은 왜 느려질까 리액트 앱이 느려질 때 많은 분이 먼저 memo , useMemo , useCallback 부터 떠올립니다. 하지만 실제 병목은 대개 훅이 부족해서가 아니라, 상태가 너무 위에 있거나, 작은 변화가 너무 넓은 화면에 전파되거나, 리스트 렌더링과 정렬·필터링 같은 계산이 반복되기 때문에 생깁니다. 여기서 먼저 구분할 것이 있습니다. 리액트에서 리렌더링은 정상 동작입니다. 상태나 props 가 바뀌면 다시 렌더링하면서 다음 UI를 계산하는 것이 리액트의 기본 모델입니다. 문제는 그 렌더링 범위가 불필요하게 넓거나, 계산 자체가 무겁거나, 실제 DOM 반영 비용까지 커질 때입니다. 즉, 리렌더링이 있다 와 성능 문제가 있다 는 같은 말이 아닙니다. 성능 최적화의 목표는 리렌더링을 무조건 없애는 것이 아니라, 사용자 행동에 비해 과도한 계산과 전파를 줄이는 것입니다. 성능 최적화의 첫 단계: 상태 소유권 좁히기 프론트엔드에서 가장 먼저 봐야 할 것은 데이터 흐름입니다. 리액트는 부모에서 자식으로 내려가는 단방향 흐름을 가지므로, 어떤 상태...