CodeBlanks Logo Icon CodeBlanks

Challenge - Performance optimization

JavaScript course · Expert · Lesson 59/63

Build a search-suggestion function with memoization, debounce and performance measurement.

Fast search suggestions

In this challenge you will write a fast search-suggestion function. To avoid recomputing the same query you use memoization: results are stored in a Map and returned immediately if the key exists.

To coalesce input you write debounce(fn, ms); the returned function clears the previous timer on every call and sets a new setTimeout. The callback then runs only when typing settles.

To measure time you use performance.now(); it returns a millisecond-resolution timestamp.

Exercise Debounced memoized search suggestion

Write a memoize(fn) function: the returned function takes a key, returns the cached result if the Map has it, otherwise computes and stores it. Then write debounce(fn, ms): the returned function clears the previous timer with clearTimeout on every call and sets a setTimeout. Finally add a call to performance.now() to measure elapsed time.

Show example solution
Start with function memoize(fn) { const cache = new Map(); return function(key) { if (cache.has(key)) return cache.get(key); const r = fn(key); cache.set(key, r); return r; }; }. Then write function debounce(fn, ms) { let t; return function(...args) { clearTimeout(t); t = setTimeout(() => fn.apply(this, args), ms); }; }. Finally add const start = performance.now();.

Example solution:
function memoize(fn) {
  const cache = new Map();
  return function(key) {
    if (cache.has(key)) return cache.get(key);
    const result = fn(key);
    cache.set(key, result);
    return result;
  };
}

function debounce(fn, ms) {
  let timer;
  return function(...args) {
    clearTimeout(timer);
    const start = performance.now();
    timer = setTimeout(() => fn.apply(this, args), ms);
  };
}

Test yourself

  1. What is the difference between debounce and throttle?

    function debounce(fn, ms) {
      let t;
      return function(...args) {
        clearTimeout(t);
        t = setTimeout(() => fn.apply(this, args), ms);
      };
    }
    • debounce fires after settling, throttle fires at fixed intervals
    • They do the same thing
    • throttle cancels the callback immediately
    • debounce fires the callback on every call
    Show answer

    debounce fires after settling, throttle fires at fixed intervals — Correct! debounce batches calls and runs once after settling; throttle runs at fixed intervals.

  2. Memoization cache check

    function memoize(fn) {
      const cache = new Map();
      return function(key) {
        if (____) {
          return cache.get(key);
        }
        const result = fn(key);
        cache.set(key, result);
        return result;
      };
    }
    Show answer
    function memoize(fn) {
      const cache = new Map();
      return function(key) {
        if (cache.has(key)) {
          return cache.get(key);
        }
        const result = fn(key);
        cache.set(key, result);
        return result;
      };
    }
  3. Match the performance concepts

    memoization
    Cache results
    debounce
    Fire after settling
    performance.now()
    Measure time
    clearTimeout
    Cancel timer

All lessons in Expert