Today I Learned
- 클로저의 성질을 이용한 고차함수 활용
- 자바스크립트의 성능향상을 위해 사용되는 함수들로 underscore나 lodash 등의 라이브러리에 구현되어 있는 것을 가져다 쓸 수도 있다.
Memoize
- 함수가 실행되면 결과값을 캐싱하여 같은 작업이 반복될 때 다시 연산할 필요 없이 저장된 값을 불러와 사용하여 시간과 리소스 소모를 줄일 수 있다.
- 연산하는 데 비용이 큰 함수의 경우에 사용해주면 좋다.
const memoize = (func) => {
const cache = {};
return function (...args) {
const key = JSON.stringify(args);
if (!(key in cache)) {
return cache[key] = func(...args);
} else {
return cache[key];
}
}
}
Throttle
- 함수가 호출된 후 주어진 시간 동안 다시 호출되지 않도록 함. (주어진 시간 동안 함수는 최대 1번 호출됨)
- 첫 번째 호출은 바로 실행되고, 그 이후에는 주어진 시간 동안 아무것도 실행하지 않고 주어진 시간이 끝나면 마지막 호출을 실행
- scroll 이벤트는 스크롤을 조금만 움직여도 아주 많은 이벤트가 발생한다. scroll 이벤트 하나하나에 반응하여 콜백함수가 실행되면 성능이 저하될 수 있기 때문에 throttle을 사용하여 마지막 실행 후 일정 시간동안은 다시 실행되지 않도록 할 수 있다.
const throttle = (func, waits) => {
let lastFunc;
let lastRan;
return function(...args) {
const context = this;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(() => {
if ((Date.now() - lastRan) >= waits) {
func.apply(context, args);
lastRan = Date.now();
}
}, (waits - (Date.now() - lastRan)));
}
}
}
Debounce
- 함수가 반복적으로 호출될 경우 바로 실행하지 않고 일정 시간을 기다린 뒤 그 사이 다시 호출이 일어나지 않았을 경우 마지막으로 발생한 호출 한번만 실행함.
- 사례 : 검색창에 검색어를 입력하면 엔터를 누르기 전에 검색 결과를 ajax로 불러와 보여준다고 할 때, 한 글자가 바뀔 때마다 이벤트를 발생시키면 불필요하게 너무 많은 요청이 발생하기 때문에 그 대신 마지막 입력 후 일정 시간이 지나도록 새로운 입력이 없으면 요청하도록 debounce를 사용해 구현할 수 있다.
const debounce = (func, waits) => {
let timeoutId;
return function (...args) {
const context = this;
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(context, args)
}, waits);
}
}