[React] 최적화와 메모이제이션

박소정·2023년 12월 15일
2

React

목록 보기
18/26
post-thumbnail

최적화 🧐

한마디로 웹 서비스의 성능을 개선하는 기술이다.
최적화가 잘 된 웹 서비스는 사용자를 불필요하게 기다리지 않게 만들며, 결론적으로 서비스에 대한 사용자 경험을 긍정적으로 만든다.
최적화의 방법으로는 코드, 폰트, 이미지 파일의 크기를 줄이는 등 여러 기술이 있지만 그 중 기본이 되는 리액트의 연산 낭비를 줄이는 방법이 있다.

메모이제이션(Memoization) 🧐

리액트 앱에서 연산 최적화는 대부분 메모이제이션 기법을 이용한다.
특정 입력에 대한 결과를 계산해 메모리 어딘가에 저장했다가 동일한 요청이 들어오면 저장한 결과 값을 제공해 빠르게 응답하는 기술이다.
결과적으로 불필요한 연산을 줄여 주어 프로그램의 실행 속도를 빠르게 만든다.

useMemo

메모이제이션 기법을 이용해 연산의 결과 값을 기억했다가 필요할 때 사용함으로써 불필요한 함수 호출을 막아 주는 리액트 훅이다.

  • 문제점 파악하기

    다음은 현재 진행중인 프로젝트 '할 일 관리'의 일부 코드입니다. (전체 코드는 여기)
    할 일 아이템을 분석하는 함수 analyzeTodo는 페이지 상에 총 개수, 완료, 해야하는 일을 렌더링 해주며 todo에 저장한 아이템 개수에 비례해 수행할 연산량이 증가한다.
    연산량을 줄이려면 함수 analyzeTodo를 불필요하게 호출하는 일이 일어나지 않아야 한다.

    import "./TodoList.css";
    import TodoItem from "./TodoItem.js";
    import { useState } from "react";

    const TodoList = ({ todo, onUpdate, onDelete }) => {
      const [search, setSearch] = useState("");
      const onChangeSearch = (e) => {
        setSearch(e.target.value);
      };

      const getSearchResult = () => {
        return search === ""
          ? todo
          : todo.filter((it) => it.content.toLowerCase().includes(search));
      };

      const analyzeTodo = () => {
        const totalCount = todo.length;
        const doneCount = todo.filter((it) => it.isDone).length;
        const notDoneCount = totalCount - doneCount;
        return {
          totalCount,
          doneCount,
          notDoneCount,
        };
      };

      const { totalCount, doneCount, notDoneCount } = analyzeTodo();

      return (
        <div className="TodoList">
          <h4>Todo List </h4>
          <div className="situation">
            <h6>💜 총 개수: {totalCount}</h6>
            <h6>💜 완료: {doneCount}</h6>
            <h6>💜 해야하는 일: {notDoneCount}</h6>
          </div>
          <input
            value={search}
            onChange={onChangeSearch}
            className="searchbar"
            placeholder="검색어를 입력하세요"
          />
          <div className="list_wrapper">
            {getSearchResult().map((it) => (
              <TodoItem
                key={it.id}
                {...it}
                onUpdate={onUpdate}
                onDelete={onDelete}
              />
            ))}
          </div>
        </div>
      );
    };
    export default TodoList;
  • 사용법

    const value = useMemo(callback, deps);
  • 적용

  const analyzeTodo = useMemo(() => {
    const totalCount = todo.length;
    const doneCount = todo.filter((it) => it.isDone).length;
    const notDoneCount = totalCount - doneCount;
    return {
      totalCount,
      doneCount,
      notDoneCount,
    };
  }, [todo]);

  const { totalCount, doneCount, notDoneCount } = analyzeTodo;

💡

  • 컴포넌트에서 상태를 다루는 작업들을 추상화시킨 로직들의 집합이다.

0개의 댓글