[TIL] JS - 고차함수 memoize, throttle, debounce

10153 단어 TILTIL

Today I Learned

  • 클로저의 성질을 이용한 고차함수 활용
  • 자바스크립트의 성능향상을 위해 사용되는 함수들로 underscorelodash 등의 라이브러리에 구현되어 있는 것을 가져다 쓸 수도 있다.

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; // timerid of last invocation
  let lastRan; // timestamp of last invocation 
  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)));
    }
  }
}
// cf. JS에서 시간 단위는 ms (1000ms = 1s)

Debounce

  • 함수가 반복적으로 호출될 경우 바로 실행하지 않고 일정 시간을 기다린 뒤 그 사이 다시 호출이 일어나지 않았을 경우 마지막으로 발생한 호출 한번만 실행함.
  • 사례 : 검색창에 검색어를 입력하면 엔터를 누르기 전에 검색 결과를 ajax로 불러와 보여준다고 할 때, 한 글자가 바뀔 때마다 이벤트를 발생시키면 불필요하게 너무 많은 요청이 발생하기 때문에 그 대신 마지막 입력 후 일정 시간이 지나도록 새로운 입력이 없으면 요청하도록 debounce를 사용해 구현할 수 있다.
const debounce = (func, waits) => {
	let timeoutId;
  return function (...args) {
 		const context = this;
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      func.apply(context, args)
    }, waits);
  }
}

좋은 웹페이지 즐겨찾기