예전 프로젝트들에서는 검색창을 키보드 입력시 마다 검색 요청이 되는 것이 아닌, 검색 버튼을 누르면 요청이 되는 방식이었다.
하지만 이번 블로그 프로젝트에서는 velog검색 처럼 사용자가 입력할때마다 특정 버튼을 누르지 않더라도 검색이 자동으로 되도록 하고 싶었다.
따라서 사용자가 키보드로 입력할때마다 해당 입력값을 state를 변경하고, state가 변경되면 바로 api 요청을 해서 검색된 포스트를 가져오도록 구현하였다.
사실 그렇게 구현해도 가능하지만, 그렇게 되면 클라이언트 측에서 서버로 요청을 보내고, 그럼 서버에서 Sanity 데이터베이스에 접근하고, 일치하는 데이터가 있으면 받아오고, 서버에서 다시 클라이언트로 응답을 보내는 과정이,,, 사용자가 한글자를 입력할때마다 네트워크 요청을 하게 되는 방식이지 않나😂😂
이런 방식은 사용자도 원하지 않고, 성능적인 측면에서도 좋지 않을 것이란 판단을 했다.
과도한 요청에 따른 성능 저하를 어떻게 개선할 수 있을까 하며 고민하다 발견한게 바로 Debounce와 Throttle방식이다.
Debouncing 이란?
디바운스란, 연이어 호출되는 함수들 중 가장 마지막 함수만 호출하도록 하는 방식이다.
즉, 요청이 들어오고 일정 시간을 기다린 후 요청을 수행하며, 만약 일정 시간 안에 같은 요청이 추가로 들어오면 이전 요청은 취소하게 된다.
⇒ 주로 ajax 검색에 자주 쓰이는데, 이 방식을 사용하면, 사용자가 키워드를 입력하다가 멈추면!! 네트워크 요청을 하는 방식을 사용할 수 있다.
Throttling이란?
반면, Throttling이란, 마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 방식이다.
⇒ 스크롤을 올리거나, 내릴때 (ex. 무한스크롤) 에서 자주 사용된다고 한다. throlling을 설정해 두지 않는다면 스크롤을 올리고 내릴때마다 scroll event가 발생할 것이다. 그럴때 throlling을 사용하여 일정 시간에 한번씩만 실행되도록 제한을 걸면 성능이 개선될 것이다.
Debounce Hook을 만들어보자
// useDebounce.js import { useState, useEffect } from 'react'; export default function useDebounce(value:string, delay:number) { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value, delay]); return debouncedValue;
- value가 변경이 될때마다 useEffect가 실행이 된다.
- 바로 state값을 변경하는 것이 아닌, setTimeout 함수를 통해 delay시간만큼 timeout을 설정한다.(ex. 1초 후에 debounceValue 상태값을 변경해라)
- 만약 delay시간 전에 또 value가 변경이 되어 useEffect이 실행되면, 이전에 설정해주었던 timeout은 clearTimeout에 의해 해제한다.
- 그리고 만약 사용자가 입력을 멈추면, 마지막에 setTimeout에 등록되었던 함수가 실행되어, debounceValue가 업데이트 되어 반환될 것이다!!
- 그럼 이 기능을 사용하는 컴포넌트에서 변경된 값을 받아, 네트워크 요청을 하면 된다.
구현전
한글자 입력마다 검색 요청이 된다. (정신 사나워)

구현후(개선 결과)
react를 모두 입력한 후 한템포 쉬면, 검색 결과가 나타나는 것을 확인 할 수 있다.
