Skip to main content

Memoization, explained.

Published 2021/09/21 14:00

Is your function running slow?

There is something you could, and should, do about it so that it runs faster.

It's called "memoization". What is it and how does it work?

Let's explain:

Suppose you are developing an app that manages your users.

That app is written in Javascript.

In that app, there's a function that gets the user's details by their ID.

Something like this:

function getUserById(id){

}

That function makes an API call which gets the user information from a database:

async function getUserById(id){
    return await axios.get(`https://api.myapp.com/users/${id}`).data
}

So for example to get the user with ID 234, you'd make this call to the function:

async function runApp(){
    let user = await getUserById(234)
    console.log(user)
}

Because this function makes API calls, it can sometimes get rather slow.

Now, because of how the app works, you'd need to make several calls to the function with the same user ID.

async function runApp(){
    let user1 = await getUserById(234)
    console.log(user)

    let user2 = await getUserById(234)
    console.log(user)
}

Every time you make that call, it will make another request to the API so that it can give you the exact same result.

This will waste time and data, especially if you're low in either of these.

What if there was a way to optimise this function so that it doesn't need to make the same requests over and over again?

You can do this, with a technique called "Memoization"!

Memoization is basically a technique which stores the returned value of a function for specified arguments in an array, so that when the function is called again with the same arguments, it gets those values back much much faster.

Let's go back to our getUserById function and try and make it faster:

async function getUserById(id){
    return await axios.get(`https://api.myapp.com/users/${id}`).data
}

We'll start by creating an empty array which will contain our stored values from our function:

let storedValues = []

async function getUserById(id){
    return await axios.get(`https://api.myapp.com/users/${id}`).data
}

Next, we're going to update getUserById so that it checks whether the result for a specific user ID is stored in storedValues:

let storedValues = []

async function getUserById(id){
    if(storedValues[id] === undefined){
        return await axios.get(`https://api.myapp.com/users/${id}`).data
    }
}

Next, we'll update getUserById again so that if the value for a specific ID is stored in the storedValues array, it will return that value from the array and not perform an API request:

let storedValues = []

async function getUserById(id){
    if(storedValues[id] === undefined){
        let user = await axios.get(`https://api.myapp.com/users/${id}`).data
        return user
    }
    else{
        return storedValues[id]
    }
}

Finally, the function will store the returned user details to the storedValues array for future use:

let storedValues = []

async function getUserById(id){
    if(storedValues[id] === undefined){
        let user = await axios.get(`https://api.myapp.com/users/${id}`).data
        storedValues[id] = storedValues
        return user
    }
    else{
        return storedValues[id]
    }
}

Now, when the function is called, it will only make a request once for each ID. Each request after that would be much much faster since we've stored the return data in the array.

As a result, your app will perform much faster and your users will be much happier as a result!

Explained (34 part series)

  1. Javascript Scopes, explained.
  2. Javascript Promises, explained.
  3. Accessibility, explained.
  4. React, explained
  5. Should I use forEach() or map()?
  6. Should I use Flexbox or CSS Grid?
  7. Docker, explained.
  8. Unit testing, explained
  9. Git, explained.
  10. Typescript, explained.
  11. async/await, explained.
  12. The DOM, explained.
  13. Regular expressions, explained
  14. GraphQL, explained.
  15. Vue, explained.
  16. Svelte, explained.
  17. API, explained.
  18. Javascript Hoisting, explained.
  19. Immediately Invoked Function Expressions (IIFE), explained.
  20. ARIA roles, explained.
  21. Test-driven Development, explained.
  22. ARIA live regions, explained.
  23. aria-label in accessibility, explained.
  24. Type coercion in Javascript, explained.
  25. Variables, explained.
  26. if statements, explained.
  27. Arrays, explained.
  28. Currying in Javascript, explained.
  29. Memoization, explained.
  30. For loops, explained.
  31. Javascript Prototypes, explained.
  32. React Hooks, explained.
  33. Graph databases, explained.
  34. MongoDB, explained.
2021 Savvas Stephanides
Buy me a coffee
Some icons from Freepik