Next.js
React 폼 입력 성능이 떨어질 때 원인 추적
React 폼 입력이 느려질 때 체계적으로 성능 문제를 찾고 해결하는 방법.
React 폼을 사용하다가 어느 순간부터 입력이 느려지는 경우가 있다. 타이핑할 때마다 지연이 생기거나, 폼 제출이 오래 걸린다. 이런 문제는 검색해서 들어온 상황이라면 바로 재현 조건부터 잡는 편이 빠르다.
문제의 범위 정의
먼저 정확히 어느 부분이 느린지 파악해야 한다:
- 전체 앱이 느린가? (다른 페이지도 느린가?)
- 특정 폼만 느린가?
- 특정 입력 필드만 느린가?
이를 통해 문제의 범위를 크게 줄일 수 있다.
렌더링 조건 확인
가장 흔한 원인은 불필요한 리렌더링이다. React DevTools Profiler를 사용하자:
npm run build
# 브라우저에서 입력하면서 React DevTools Profiler로 기록
Profiler에서 어떤 컴포넌트가 자주 리렌더링되는지 확인할 수 있다. 만약 폼 컴포넌트 전체가 입력할 때마다 리렌더링된다면 useMemo나 useCallback으로 최적화해야 한다.
상태 관리 점검
상태 구조가 너무 크면 상태 업데이트할 때마다 전체 컴포넌트가 리렌더링될 수 있다:
// 비효율적: 한 필드만 바뀌어도 전체 폼이 리렌더링됨
const [formData, setFormData] = useState({
name: '',
email: '',
phone: '',
// ... 많은 필드들
});
// 효율적: 각 필드별로 상태 분리
const [name, setName] = useState('');
const [email, setEmail] = useState('');
또는 useReducer를 사용해서 상태 업데이트를 최적화할 수 있다.
이벤트 핸들러 최적화
onChange 핸들러가 복잡한 계산을 하고 있지는 않은지 확인하자:
// 느린 예
const handleChange = (e) => {
const value = e.target.value;
// 무거운 계산이나 API 호출
validateEmail(value);
checkAvailability(value);
setEmail(value);
};
// 빠른 예
const handleChange = (e) => {
setEmail(e.target.value);
};
// 유효성 검사는 별도로
useMemo(() => validateEmail(email), [email]);
디바운싱과 쓰로틀링
API 호출을 하는 경우 디바운싱을 사용해서 요청 빈도를 줄여야 한다:
import { useDeferredValue } from 'react';
function Form() {
const [input, setInput] = useState('');
const deferredInput = useDeferredValue(input);
useEffect(() => {
// deferredInput이 변경될 때만 API 호출
if (deferredInput) {
validateField(deferredInput);
}
}, [deferredInput]);
}
라이브러리 점검
UI 라이브러리 버전이 오래되었거나, 성능 이슈가 있는 버전을 쓰고 있을 수도 있다. 필요하면 업그레이드해보자:
npm update
npm audit
모바일 환경 테스트
모바일에서는 더 심각해 보일 수 있다. 브라우저 개발자 도구에서 CPU 쓰로틀링을 적용해서 테스트하자.
환경 차이
로컬과 운영 환경에서 성능이 다를 수 있다. 특히 네트워크 지연이 있으면 API 호출을 포함한 입력이 느려진다:
# 개발자 도구 → Network 탭에서 throttling 설정
실제 수정 순서
- Profiler로 정확히 무엇이 느린지 파악한다.
- 불필요한 리렌더링을 제거한다.
- 상태 구조를 최적화한다.
- 이벤트 핸들러를 간단하게 한다.
- 공개 화면에서 실제로 빨라졌는지 확인한다.
폼 성능은 사용자 경험에 직접 영향을 미친다. 작은 지연도 누적되면 앱을 느리게 만든다.