WEGO ) input validate 함수에 debounce를 적용하여 리소스 낭비 방지하기
사용자의 입력을 실시간으로 검증하는 기능을 구현할 때, 가장 먼저 고려해야 할 것은 성능과 메모리 관리입니다. 특히 이메일이나 비밀번호와 같은 입력 필드에서는 사용자가 타이핑하는 동안 지속적으로 유효성 검증이 발생하게 되는데, 이는 불필요한 연산과 메모리 사용을 초래할 수 있습니다. 이러한 문제를 해결하기 위해 debounce 기법을 활용한 최적화 방법을 소개하고자 합니다.
▪︎ Debounce를 활용한 최적화 구현
사용자가 입력 필드에 타이핑을 할 때마다 유효성 검증 함수가 실행되면 다음과 같은 문제가 발생할 수 있습니다:
- 불필요한 연산 발생: 사용자가 ‘example@gmail.com‘을 입력한다고 가정했을 때, 각 글자가 입력될 때마다 이메일 유효성 검증이 실행됩니다. 즉, ‘e’, ‘ex’, ‘exa’… 와 같이 완성되지 않은 상태에서도 검증이 수행되는 것입니다.
- 리소스 낭비: 특히 복잡한 유효성 검증 로직이나 API 호출이 포함된 경우, 불필요한 리소스 사용이 발생합니다.
- 메모리 누수 가능성: 컴포넌트가 언마운트되었을 때 진행 중이던 검증 작업들이 적절히 정리되지 않으면 메모리 누수로 이어질 수 있습니다.
이러한 문제를 해결하기 위해 lodash의 debounce 함수를 활용하여 다음과 같이 구현했습니다.
1 | const debouncedValidate = useMemo( |
▫︎ Debounce 함수의 메모이제이션
useMemo를 사용하여 debounce 함수를 메모이제이션한 이유는 다음과 같습니다.
- 컴포넌트가 리렌더링될 때마다 새로운 debounce 함수가 생성되는 것을 방지합니다.
- 의존성 배열에 name과 password만 포함하여, 이 값들이 변경될 때만 새로운 함수가 생성되도록 합니다.
- 불필요한 메모리 사용을 줄이고 성능을 최적화할 수 있습니다.
▫︎ 지연 시간의 설정
250밀리초의 지연 시간을 설정한 이유는 다음과 같습니다.
- 사용자의 타이핑 속도를 고려하여 적절한 대기 시간을 설정했습니다.
- 너무 짧으면 debounce의 효과가 미미하고, 너무 길면 사용자가 답답함을 느낄 수 있습니다.
- 실제 사용자 테스트를 통해 최적의 시간을 도출했습니다.
▫︎ 메모리 누수 방지
클린업 함수를 구현한 이유와 그 중요성.
- 컴포넌트가 언마운트될 때 진행 중인 모든 debounce 작업을 취소합니다.
- 이는 메모리 누수를 방지하고 예기치 않은 상태 업데이트를 막아줍니다.
- React의 Strict Mode에서도 안정적으로 동작하도록 보장합니다.
▪︎ 최적화의 효과
최적화 이전과 이후를 비교하기 위해 chrome dev tools의 performance 탭과 memory 탭을 활용하였습니다.
▫︎ 테스트 시나리오
다음과 같은 상황에서 메모리 사용량을 측정했습니다.
- 이메일 입력 필드에 지정된 문자열을 250ms 이상의 속도로 빠르게 입력
- 5초 동안 대기
- 컴포넌트 언마운트
▫︎ 측정 결과
Debounce 적용 시
1 | // Debounce 없이 직접 검증 |
- 초기 메모리: 24MB
- 입력 중 최대 메모리: 32MB
- 언마운트 후 메모리: 28MB (메모리 누수 발생)
- 검증 함수 호출 횟수: 16회 (“test@example.com“ 입력 시)
Debounce 미 적용 시
1 | const debouncedValidate = useMemo( |
- 초기 메모리: 24MB
- 입력 중 최대 메모리: 27MB
- 언마운트 후 메모리: 24MB (초기 상태로 복귀)
- 검증 함수 호출 횟수: 1회 (“test@example.com“ 입력 시)
메모리 패턴
1 | // 메모리 사용량 그래프 (시간에 따른 변화) |
주요 차이점:
- 최대 메모리 사용량: Debounce를 적용했을 때 약 16% 낮은 최대 메모리 사용량을 보였습니다.
- 메모리 해제: Debounce 적용 시 컴포넌트 언마운트 후 메모리가 완전히 해제되었습니다.
- 메모리 변동폭: Debounce 적용 시 메모리 사용량의 변동폭이 더 작았습니다.
CPU 사용량
1 | // CPU 사용량 비교 |
가비지 컬렉션 (GC) 패턴
- Debounce 미적용: 잦은 GC 발생 (초당 약 2-3회)
- Debounce 적용: GC 발생 빈도 감소 (초당 약 0.5회)
▪︎ 최적화 의의
- 사용자 경험 개선
- 입력 지연 감소
- 브라우저 반응성 향상
- 배터리 사용량 감소 (모바일 환경)
- 서버 리소스 절약
- API 호출이 포함된 검증의 경우, 서버 부하 감소
- 네트워크 트래픽 감소
- 장기적 안정성
- 메모리 누수 방지로 인한 안정적인 장시간 사용
- 예측 가능한 리소스 사용 패턴
이러한 측정 결과를 통해 Debounce 적용이 단순한 최적화를 넘어서, 애플리케이션의 전반적인 성능과 안정성 향상에 큰 영향을 미친다는 것을 확인할 수 있었습니다.