As our systems mature and begin to do more complex calculations, the need for speed grows, and process optimization becomes a need. When we overlook this issue, we end up with applications that take a long time to run and demand a large number of system resources.
In this article, we are going to look at memoization which is one technique that can help us significantly reduce processing time if done the right way.
Memoization: Memoization is a technique for speeding up applications by caching the results of expensive function calls and returning them when the same inputs are used again.
Let us try to understand this by breaking the definition into small parts.
- Expensive Function Calls: Time and memory are the two most important resources in computer applications. As a result, an expensive function call is one that consumes large amounts of these two resources due to extensive calculation during execution.
- Cache: A cache is just a temporary data store that stores data in order to serve future requests for that data more quickly.
Importance of Memoization: When a function is given in input, it performs the necessary computation and saves the result in a cache before returning the value. If the same input is received again in the future, it will not be necessary to repeat the process. It would simply return the cached answer from the memory. This will result in a large reduction in a code’s execution time.
Memoization in Javascript: In JavaScript, the concept of memorization is based mostly on two ideas. They are as follows:
- Closures
- Higher-Order Functions
Closures: Before talking about closure, let’s take a quick look at the concept of lexical scope in JavaScript. Lexical scoping defines the scope of a variable by the position of that variable declared in the source code.
Example:
JavaScript let hello = "Hello"; function salutation() { let name = "Aayush"; console.log(`${hello} ${name}!`); }
In the above code:
- The variable hello is a global variable. It can be accessed from any location, including the salutation() function.
- The variable name is a local variable that can only be accessed within the salutation() function.
According to lexical scoping, the scopes can be nested and the inner function can access the variables declared in its outer scope. Hence in the code below, the inner function greet() has access to the variable name.
JavaScript function salutation() { let name = "Aayush"; function greet() { console.log(`Hello ${name}!`); } greet(); }
Now let’s modify this salutation() function and rather than invoking the function greet(), we return the greet() function object.
JavaScript function salutation() { let name = 'Aayush'; function greet() { console.log(`Hello ${name}!`); } return greet; } let wish = salutation(); wish();
If we run this code, we will get the same output as before. However, it’s worth noting that a local variable is generally only present during the function’s execution. It means that when salutation() execution is completed, the name variable is no longer accessible. In this case, when we execute wish(), the reference to greet(), the name variable still exists. A closure is a function that preserves the outer scope in its inner scope.
Higher-Order Functions: Higher-order functions are functions that operate on other functions by taking them as arguments or returning them. For example, in the above code, salutation() is a higher-order function.
Now, using the famous Fibonacci sequence, let’s examine how memoization makes use of these concepts.
Fibonacci Sequence: The Fibonacci sequence is a series of numbers that begins with one and ends with one, following the rule that each number (called a Fibonacci number) is equal to the sum of the two numbers before it.
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...
A simple recursive solution to this problem would be:
JavaScript function fibonacci(n) { if (n < 2) return 1; return fibonacci(n - 1) + fibonacci(n - 2); }
If we were to plot the recursion tree for the above function when n=4, it would look like this,
As you may notice, there are too many redundant computations.
Let’s try to fix this with memoization.
JavaScript function memoisedFibonacci(n, cache) { cache = cache || [1, 1] if (cache[n]) return cache[n] return cache[n] = memoisedFibonacci(n - 1, cache) + memoisedFibonacci(n - 2, cache); }
We change the function in the code sample above to accept an optional argument called cache. We use the cache object as a temporary memory to store Fibonacci numbers with their associated indices as keys, which can then be retrieved as needed later in the execution.

If we plot the execution time, for both versions of the Fibonacci function, it is quite evident that the employment of the memoization technique leads to significant time reduction.
Practical Example: Javascript Memoization for a Web Response: To demonstrate this, we’ll use an example Idioms API. It is a simple REST API built using Node.js.
Response times before Memoization: Following is a simple Express.js route that returns all of the idioms stored within the API. In this situation, each call will result in a database query.
JavaScript import express from 'express'; const router = express.Router(); import { getAllIdioms } from '../services/database.js'; router.get('/', async function(req, res, next) { try { res.json(await getAllIdioms()); } catch (err) { console.log('Error while getting idioms ', err.message); res.status(err.statusCode || 500).json({ 'message': err.message }); } })
Let’s have a look at how long it takes for this approach to respond. I ran a quick load test using the Vegeta load testing tool.

Response times after Memoization: Now let’s modify the above code to add memoization. For the purposes of this illustration, I’ve used the p-memoize package.
JavaScript import express from 'express'; const router = express.Router(); import { getAllIdioms } from '../services/database.js'; import pMemoize from 'p-memoize'; const ONE_MINUTE_IN_MS = 60000; const memGetAllIdioms = pMemoize(getAllIdioms, { maxAge: ONE_MINUTE_IN_MS }); router.get('/', async function (req, res, next) { try { res.json(await memGetAllIdioms()); } catch (err) { console.log('Error while getting idioms ', err.message); res.status(err.statusCode || 500).json({'message': err.message}); } })
As a result,

When compared to the previous graph, we can observe that the Express.js route that uses memoization is significantly faster than the non-memoize equivalent.
Similar Reads
JavaScript Linked List Programs
JavaScript Linked List Programs contain a list of articles based on programming. Linked List is a linear data structure that stores data in linearly connected nodes. Linked lists store elements sequentially, but doesnât store the elements contiguously like an array. S. NoArticles1JavaScript Program
5 min read
Explain Implement a memoization helper function
What is memoization? It is a programming technique that is used to increase the efficiency of function by storing the previous values that function has already been calculated. It increases the program efficiency by caching the results of the function calls. We often waste time by calling the functi
5 min read
JavaScript Map Coding Practice Problems
Maps are an essential data structure used for storing key-value pairs. They provide efficient lookups, insertions, and deletions, and are widely used for implementing dictionaries, caches, and many other applications. This curated list of JavaScript Map Coding Practice Problems will help you master
2 min read
What is Memoization in React ?
Memoization is a powerful optimization technique used in React to improve the performance of applications by caching the results of expensive function calls and returning the cached result when the same inputs occur again. In this article, we will learn more about the concept of memoization and its
6 min read
Lodash _.memoize() Method
Lodash _.memoize() method is used to memorize a given function by caching the result computed by the function. If the resolver is issued, the cache key for storing the result is determined based on the arguments given to the memoized method. By default, the first argument provided to the memoized fu
2 min read
How to write a simple code of Memoization function in JavaScript ?
Memoization is a programming technique that we used to speed up functions and it can be used to do whenever we have an expensive function ( takes a long time to execute). It relies on the idea of cache {}. A cache is just a plain object. It reduces redundant function expression calls. Let's understa
3 min read
JavaScript Linked List Coding Practice Problems
Linked Lists are one of the most fundamental data structures in JavaScript, allowing efficient insertion and deletion of elements at the beginning or end of a list. This curated list of JavaScript Linked List Coding Practice Problems will help you master linked list operations. Whether you're a begi
2 min read
JavaScript Set Coding Practice Problems
Sets are an important data structure in JavaScript that store unique values of any type, whether primitive or object references. A Set is useful for scenarios where you want to eliminate duplicate values or check for membership efficiently. Sets are unordered collections, meaning the elements are no
2 min read
JavaScript Heap Coding Practice Problems
Heaps are an essential data structure in JavaScript used for efficiently managing priority-based tasks. A Heap is a specialized tree-based structure that allows for quick retrieval of the smallest or largest element, making it useful for priority queues, scheduling algorithms, and graph algorithms l
2 min read
JavaScript Queue Coding Practice Problems
Queues are an essential data structure used for managing data in a First In, First Out (FIFO) manner. This curated list of JavaScript Queue Coding Practice Problems will help you master queue operations. Whether you're a beginner or an experienced developer, these problems will enhance your queue ma
1 min read