in

How to memoize functions and values ​​in JavaScript and React

pexels jonas svidras 785418

[ad_1]

Memoization is an optimization technique similar to caching. It works by saving the previous results of a function call and using those results the next time the function is run. This is especially useful for computationally intensive apps that make repeated function calls with the same parameters.


Memoization can be used in several different ways, both in plain JavaScript and React.

Memoization in JavaScript

To memoize a function in JavaScript, you need to cache the result of that function. A cache can be an object with arguments as keys and results as values.

Calling this function first checks if the result exists in the cache before executing. If so, return the cached result. otherwise it will be executed.

Consider this function:

 function square(num) {
    return num * num
}

This function takes an argument and returns its square.

To run a function, call it with a number like this:

 square(5) 

With 5 as the argument, square() runs very fast. However, computing 70,000 squared introduces a significant delay. Not much, but still late. Now, if you call the function multiple times and pass 70,000, there will be a delay on each call.

You can use memoization to eliminate this delay.

 const memoizedSquare = () => {
    let cache = {};
    return (num) => {
      if (num in cache) {
        console.log('Reusing cached value');
        return cache[num];
      } else {
        console.log('Calculating result');
        let result = num * num;

        // cache the new result value for next time
        cache[num] = result;
        return result;
      }
    }
  }

In this example, the function checks to see if it has previously computed the result by checking if the result exists in the cache object. Returns the already computed value, if any.

When the function receives a new number, it computes the new value, caches the result, and returns it.

This example is also very simple, but it illustrates how memoization can work to improve program performance.

Only pure functions should be noted. These functions return the same result when passed the same arguments. Using memoization on non-pure functions does not improve performance, but adds overhead. This is because every time you memoize a function, you choose speed over memory.

Memoization in React

If you’re looking to optimize your React components, React provides memoization via the useMemo() hook, React.memo, and useCallBack().

Using useMemo()

useMemo() is a React hook that accepts functions and dependency arrays.

 const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

Remember the value returned from that function. The values ​​in the dependencies array indicate when the function will be executed. Only if they change the function will be executed again.

For example, the following App component has a memoized value called Result.

 import { useMemo } from "react"
function App(value) {
   const square = (value) => {
     return value * value
   }

   const result = useMemo(
     () => square(value),
     [ value ]
   );

   return (
     <div>{result(5)}</div>
   )
}

The App component calls square() on every render. Especially if the square() function is expensive, the performance will suffer when the App component is rendered many times due to React prop changes or state updates.

However, useMemo() caches the return value, so the square function won’t be executed on each re-render unless the arguments in the dependency array change.

Using React.memo()

React.memo() is a higher order component that accepts React components and functions as arguments. This function determines when the component should be updated.

This function is optional and if not specified, React.memo will do a shallow copy comparison of the component’s current props and previous props. If the props are different, it will trigger an update. If the props are the same, skip re-rendering and reuse the memoized value.

The optional function accepts previous props and next props as arguments. Then you can explicitly compare those props to decide whether to update the component.

 React.memo(Component, [areEqual(prevProps, nextProps)])

Let’s first look at an example without optional function arguments. Below is a component called comment that accepts name and email props.

 function Comments ({name, comment, likes}) {
   return (
       <div>
           <p>{name}</p>
           <p>{comment}</p>
           <p>{likes}</p>
       </div>
   )
}

The memoized comment component wraps React.memo like this:

 const MemoizedComment = React.memo(Comment)

You can call it and call it like any other React component.

 <MemoizedComment name="Mary" comment="Memoization is great" likes=1/>

If you want to do the prop comparison yourself, pass the following function as the second argument to React.memo.

 import React from "react"

function checkCommentProps(prevProps, nextProps) {
   return prevProps.name === nextProps.name
        && prevProps.comment === nextProps.comment
        && prevProps.likes === nextProps.likes
}

const MemoizedComment = React.memo(Comments, checkCommentProps)

If checkProfileProps returns true, the component will not be updated. Otherwise it will be re-rendered.

Custom functions are useful if you want to customize re-rendering. For example, you can use this to update the comments component only when the number of likes changes.

Unlike the useMemo() hook, which only memorizes the function’s return value, React.memo memoizes the entire function.

Only use React.memo for pure components. Also, to reduce comparison costs, memoize only components whose props change frequently.

Using useCallBack()

You can use the useCallBack() hook to memoize function components.

 const memoizedCallback = useCallback(
  () => {
    doSomething(a, b);
  },
  [a, b],
);

The function will update only if the value of the dependent array changes. The hook works like the useMemo() callback, but instead of memorizing the value, it memorizes the function component between renders.

Consider the following example of a memoized function calling an API.

 import { useCallback, useEffect } from "react";
const Component = () => {
   const getData = useCallback(() => {
     console.log('call an API');
   }, []);
   useEffect(() => {
     getData();
   }, [getData]);
 };

The getData() function called in useEffect is called again only if the getData value changes.

Need a note?

In this tutorial, you learned what memoization is, its benefits, and how to implement memoization in JavaScript and React. But you should know that React is already fast. In most cases, memoizing a component or value increases the comparison cost and does not improve performance. For this reason, only note the expensive components.

React 18 also introduced new hooks like useId, useTransition and useInsertionEffect. You can use them to improve the performance and user experience of your React application.

[ad_2]

Source link

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings

    Orb-Weaver Spiders: A Primer – Pest control technology

    ecommerce wb

    7 Best Ecommerce Website Builders for Online Stores in 2022