우리가 평소에 사용하는 웹서비스의 검색은 어떻게 이루어지는 것일까요?
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
입니다.
사용하기 위해 터미널에서 아래의 코드를 입력해 라이브러리를 설치해줍니다.
yarn add uuid
설치가 완료되면, uuid
를 import
시켜준뒤 필요한 key
에 넣어주면 됩니다.
import { v4 as uuidv4 } from "uuid"
function example() {
return(
<div key={uuidv4()}>
</div>
)
}
검색버튼을 누르지 않고 검색기능이 활성화 될때, 생기는 문제가 있습니다.
바로, 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} />
</>
);
}
그럴 경우 중간 과정을 없애고 결과만 한 번에 실행해주는 것이 Debounce입니다.
사용하고 싶은 컴포넌트 상단에 debounce
를 불러봅시다.
그리고 우리가 원하는 기능을 debounce
로 감싸주시면 됩니다.
import { debounce } from 'lodash';
export default function Test2() {
const handleOnChange = debounce((e) => {
console.log(e.target.value);
}, 500);
return (
<>
<input onChange={handleOnChange} />
</>
);
}
Debounce는 setTimeout과 사용방법이 똑같습니다. debounce(콜백함수, 시간)
첫 번째 인자로는 실행시키고 싶은 함수가 들어가고, 두 번째 인자로는 시간이 들어갑니다.
debounce는 우리가 두 번째 인자로 넣어준 시간 동안 아무 일도 하지 않았을 때 콜백함수를 실행시킵니다.
즉, 사용자가 무언가를 계속 입력하고 있으면 함수를 실행시키지 않고, 사용자가 입력을 끝내고 가만히 있으면 그때 함수 결과를 보여줍니다.
Debounce의 결과는 아래와 같습니다.
처음 결과와는 다르게 Debounce를 사용하니 console.log()
에 한 번만 찍힌 것을 볼 수 있습니다.
주로 검색을 할 때 사용할 수 있습니다. 우리가 검색을 할 때 엔터를 치지 않더라도, 사용자가 입력을 멈추고 일정 시간이 지나면 자동으로 함수를 실행시켜 검색 결과를 보여주는 것입니다.