우리가 평소에 사용하는 웹서비스의 검색은 어떻게 이루어지는 것일까요?
Browser
에서 검색을 요청하면 Back-end
에서 DB
내부의 수 많은 Data 들 속에서 요청받은 keyword
를 가지고 full-scan
하게 됩니다. Data가 많을 수록 속도가 느리겠죠? 이러한 방식을 변경할 수 있습니다.
Data를 특정 키워드들로 구분지어 해당하는 글들을 모아 역인덱스 방식(Inverted Index)
으로 저장되게 된다면 특정 키워드에 대한 글들의 검색이 빠르겠죠?
이런 방식을 쉽게 만들어 주는 도구(DB)가 Elastic Search
입니다. 이 방식은 Disk
에 저장되는 방식으로 컴퓨터가 꺼져도 저장이 유지됩니다. 분명 안전하지만 속도는 조금 떨어지게 됩니다.
반면, Memory
에 저장되는 방식도 존재합니다. 이방식은 임시저장방식으로 Disk저장보다는 안정성이 떨어지지만 속도가 빠릅니다. 이러한 메모리저장기반 방식으로는 Redis
가 있습니다.
서비스를 제공하고 시간이 흐르면, 사람들의 검색에 대한 어느정도 일정 패턴이 생기게 되는데, 그렇다면 사람들이 자주 검색하게 되는 것들은 검색마다 Disk
에 가서 꺼내오는것보다는 Memory 기반 DB
에 넣어두면 그때 그때 마다 더 빠르게 제공할 수 있겠죠? 이런 방식을 검색로그 캐싱
이라고 합니다.
즉, 검색이 진행될 때, 캐싱이 되어있다면 Redis
, 캐싱되어 있지 않은 기록은 Elastic Search
방식이 사용되는 것입니다.
💡 우리가
map()
을 사용할 때key값
을 주어야 하는데 이럴때, 고유 값을 더욱 손쉽게 부여할 수 있는 라이브러리가 있습니다.
바로 uuid
uuid_github 입니다.
사용하기 위해
yarn add uuid
이후,
uuid
를 import
시켜준뒤 필요한 key
에 넣어주면 사용 가능합니다.
검색버튼을 누르지 않고 검색기능이 활성화 될때, 생기는 문제가 있습니다.
바로, page
를 변경하며 refetch
될 때, state로 관리하는 검색 input
키워드 값이 검색을 누르지 않아도 검색되는 문제입니다.
이러한 문제는 검색을 눌렀을 때 들어가있는 키워드 값을 따로 저장시켜주는 state
를 분리시켜주어야 합니다.
refetch
될때 mySearch
로 검색되는 부분을 myKeyword
로 바꿔 해결합니다.
디바운싱
이란, 연이어 발생한 이벤트를 하나의 그룹으로 묶어 처리하는 방식으로 주로 그룹에서 마지막, 혹은 처음에 처리된 함수를 처리하는 방식으로 사용됩니다.
마지막 호출이 발생한 후 일정 시간이 지날 때까지 추가적 입력이 없을 때 실행이 됩니다.
디바운싱이 사용되는 대표적 예제로는 검색기능
이 있습니다.
반면 쓰로틀링
이란, 연이어 발생한 이벤트에 대해 일정한 delay
를 포함 시켜, 연속적으로 발생하는 이벤트는 무시하는 방식으로 사용됩니다.
즉, 지정한 delay
동안 호출된 함수는 무시합니다.
쓰로틀링이 사용되는 대표적 예제는 스크롤 기능
이 있습니다
Lodash
는 자바스크립트의 유틸리티 라이브러리입니다.
내장되어 있는 유용한 함수가 많기 때문에 자주사용 됩니다.
Lodash
의 많은 기능 중 디바운싱 내용에 대해 알아보겠습니다.
먼저 Lodash
를 사용하기 위해서는 설치를 해야 합니다.
yarn add lodash
yarn add -D @types/lodash
Debounce는 반복적인 동작을 강제적으로 대기하는 것을 말합니다.
예를들어, 우리가 input에 onChange를 이용해 console.log()를 확인해 보면 우리가 하나하나 입력할 때마다 onChange가 실행됩니다.
아래 사진처럼 말이죠. 아마 여러번 보셨을겁니다.
export default function Test2() {
const handleOnChange = debounce((e) => {
console.log(e.target.value);
});
return (
<>
<input onChange={handleOnChange}></input>
</>
);
}
그럴 경우 중간 과정을 없애고 결과만 한 번에 실행해주는 것이 Debounce입니다.
사용하고 싶은 컴포넌트 상단에 Debounce를 불러봅시다.
import { debounce } from 'lodash';
그리고 우리가 원하는 기능을 debounce로 감싸주시면 됩니다.
import { debounce } from 'lodash';
export default function Test2() {
const handleOnChange = debounce((e) => {
console.log(e.target.value);
}, 500);
return (
<>
<input onChange={handleOnChange}></input>
</>
);
}
위에서 굵게 표시된 부분이 Debounce 입니다.
Debounce는 setTimeout과 사용방법이 똑같습니다. debounce(콜백함수, 시간)
첫 번째 인자로는 실행시키고 싶은 함수가 들어가고, 두 번째 인자로는 시간이 들어갑니다.
debounce는 우리가 두 번째 인자로 넣어준 시간 동안 아무 일도 하지 않았을 때 콜백함수를 실행시킵니다.
즉, 우리가 무언가를 계속 입력하고 있으면 함수를 실행시키지 않고, 우리가 입력을 끝내고 가만히 있으면 그때 함수 결과를 보여줍니다.
Debounce의 결과는 아래와 같습니다.
처음 결과와는 다르게 Debounce를 사용하니 console.log()
에 한 번만 찍힌 것을 볼 수 있습니다.
그럼 우리는 Debounce를 어떻게 활용할 수 있을까요?
주로 검색을 할 때 사용할 수 있습니다. 우리가 검색을 할 때 엔터를 치지 않더라도, 사용자가 입력을 멈추고 일정 시간이 지나면 자동으로 함수를 실행시켜 검색 결과를 보여주는 것입니다.
그러면 아주 편리하겠죠?
Debounce와 검색 Mutation을 함께 사용하는 코드는 여러분들이 직접 구현해보세요!