[TIL 0427] Optimistic-UI(옵티미스틱 UI) 성능 최적화

zitto·2023년 4월 26일
0

TIL

목록 보기
67/77
post-thumbnail

게시물의 좋아요를 누르게 되면 환경에 따라 좋아요의 수가 올라가는 속도가 다르다.
왜?

느린환경의 컴퓨터, 혹은 백엔드 컴퓨터가 굉장히 먼 곳에 있다면 해당과정이 굉장히 지연될 수 있음!


Optimistic-UI(옵티미스틱 UI)

옵티미스틱 UI란?
요청이 서버에 도달하기도 전에 화면의 값을 미리 바꿔버리는 것!


예를 들어, likeBoard를 요청하기도 전에 화면에 5로 바꿔버리고 계속해서 요청을 보내보자!

요청성공 후 6이 응답으로 돌아올때 다시 화면을 업데이트한다.
하지만 이미 옵티미스틱 UI로 6을 그려줬기때문에 유저가 보기에는 똑같은 것!

만일 중간에 네트워크 문제나 다른이유로 실패하게 된다면, 이전의 값을 응답으로 보내주고 이전의 값을 화면에 업데이트 해주도록 한다.

실제 성능을 높이는 것이 아니라 눈속임을 하자!

[실습]

import { useMutation, gql, useQuery } from "@apollo/client";
import {
  IMutation,
  IMutationLikeBoardArgs,
} from "../../../src/commons/types/generated/types";
//좋아요 갯수 가지고 오는 api _ 게시글 조회 api에서 좋아요 갯수만 뽑아 온다.
const FETCH_BOARD = gql`
  query fetchBoard($boardId: ID!) {
    fetchBoard(boardId: $boardId) {
      _id
      likeCount
    }
  }
`;
//좋아요 카운트 올리는 api
const LIKE_BOARD = gql`
  mutation likeBoard($boardId: ID!) {
    likeBoard(boardId: $boardId)
  }
`;
export default function () {
  const [likeBoard] = useMutation<
    Pick<IMutation, "likeBoard">,
    IMutationLikeBoardArgs
(LIKE_BOARD);
  const { data } = useQuery(FETCH_BOARD, {
    variables: { boardId: "6449087aaef9f000281ba1ed" },
  });
  const onClickLike = () => {
    //likeBoard 뮤테이션 함수를 실행
    void likeBoard({
      variables: {
        boardId: "6449087aaef9f000281ba1ed",
      },
      // 응답을 받고난 후 받아온 응답을 다시 fetch 해준다. -> 느리고 비효율적임.(백엔드에 요청을 한번더 해야하고 받아올때 까지 기다려야 함.)
      //refetchQueries: [
      //	{
      //		query: FETCH_BOARD,
      //		variables : {	boardId : "//게시글 아이디 넣기!" }
      //	}
      // ]
      //옵티미스틱 UI -> 캐시를 바꾸고 캐시값을 받아오는걸 기다리지 않고 바로 바꿔준다.
      optimisticResponse: {
        // 아폴로 클라이언트 캐시에 optimisticResponse버전으로 따로 저장된다.
        // 99% 확률로 성골할수 있는것만 써야한다.(그럼에도 실패시, 큰 이슈는 없음)
        likeBoard: (data?.fetchBoard.likeCount ?? 0) + 1,
      },
      // apollo 캐시를 직접 수정할 수 있었다.(백엔드 캐시가 아님!) -> 느리지만 효율적! (백엔드에 요청은 안하지만, 받아올때까지 기다려줘야 한다.)
      update(cache, { data }) {
        // modify를 사용하는 대신, writeQuery를 사용해본다.writeQuery는 추가도 가능
        cache.writeQuery({
          query: FETCH_BOARD,
          variables: { boardId: "6449087aaef9f000281ba1ed" },
          //어떻게 수정할 것인지는 아래에 적어준다.
          data: {
            // 기존값과 똑같이 받아와야 한다.
            fetchBoard: {
              // _id 와 _typename 이 꼭 있어야 적용이 된다.
              _id: "6449087aaef9f000281ba1ed",
              __typename: "Board",
              likeCount: data?.likeBoard,
            },
          },
        });
      },
    });
  };
  return (
    <div>
      <h1>옵티미스틱 UI</h1>
      <div>현재카운트(좋아요):{data?.fetchBoard.likeCount}</div>
      <button onClick={onClickLike}>좋아요 올리기!!</button>
    </div>
  );
}

❗️ 옵티미스틱 UI를 사용해야 할 곳과 사용하지 말아야 할 곳

→ 옵티미스틱 UI는 보통 실패 확률이 낮고 틀려도 괜찮은 중요하지 않은 데이터를 보여줄때 사용한다

따라서 데이터가 굉장히 중요하고 안정성이 필요할때는 옵티미스틱을 사용하면 안된다 ‼️
예시) 결제 후 잔여 금액


성능최적화를 위한 8가지 전략

profile
JUST DO WHATEVER

0개의 댓글