우아한테크코스 5기 프론트엔드

낙관적 업데이트를 통해 UX 개선하기

yoxxin 2023. 11. 3. 11:01

이 글을 동글에서 낙관적 업데이트를 도입하기까지의 과정을 담은 글입니다.

1. 문제상황

업로드한 글의 제목을 바꿀 때, 정상 응답이 오기 전까지는 수정 전 제목이 보이는 문제가 있었다.

깜빡이는 제목

기능을 사용하는 데는 문제가 없지만 사용자는 불편하게 느낄 수 있고, 인터넷이 느린 환경에서는 더욱 문제가 된다.

그래서 요청이 성공했다고 가정하고 응답이 오기 전 요청 결과를 바로 반영하는 낙관적 업데이트 도입을 고민했다.

2. 낙관적 업데이트.. 꼭 필요할까?

그 전략이 좋아보인다고 해서 무턱대고 도입할 수는 없다.

사용자의 데이터 변경 요청을 빠르게 반영할 수 있다는 장점이 있지만, 서비스에 대한 사용자의 신뢰도 하락으로도 이어질 수 있다.

 

예를 들어 글 제목 변경 요청 후 재빨리 글 발행을 요청했는데

실제로는 글 제목 변경 요청에 실패했다면 수정 전 제목으로 글이 올라갈 것이다.

UX를 개선하려고 했던게 오히려 UX 저하로 이어질 수 있다.

 

이는 이커머스나 결제 시스템과 같이 돈과 관련된 서비스일수록 더 신중하게 고려해야한다.

즉 낙관적 업데이트를 적용하려는 요청이 결제와 같이 중요한 요청과 관련되어 있다면, 단순히 UX 개선만 보고 도입하기에는 무리가 있다.

 

동글의 글 제목 변경은 위 엣지 케이스는 많이 일어나지 않는다고 판단했다.

글 제목 변경에 실패했는데 바로 뒤이어 요청한 발행에 성공하는 경우는 드물다고 생각했고,

무엇보다 글 제목을 변경했는데 이전 제목이 잠깐 보인다는 건

지금껏 다른 에디터와는 다른, 불편하고 낯선 경험을 주기 때문에 서비스에 부정적인 영향을 끼친다고 생각했다. 

 

그래서 상대적으로 이득이 더 많은 낙관적 업데이트를 도입하기로 했다.

3. 낙관적 업데이트 적용  

동글은 @tanstack/react-query를 사용하고 있다.

공식문서를 참고해 작성하면 된다.

하지만 라이브러리를 사용하든 안 하든 낙관적 업데이트의 기본 구조는 다음과 같다.

import React, { useState } from 'react';

function OptimisticUpdateExample() {
  const [data, setData] = useState([]);

  const deleteItem = (itemId) => {
    // 현재 상태를 저장하여 롤백 가능하도록 함
    const currentData = [...data];
    
    // 낙관적 UI 업데이트: 서버 응답을 기다리지 않고 바로 UI를 업데이트함
    const newData = data.filter(item => item.id !== itemId);
    setData(newData);

    // Fetch API 요청으로 실제 항목 삭제 수행
    fetch(`/api/items/${itemId}`, { method: 'DELETE' })
      .then(response => {
        if (!response.ok) {
          // 요청이 실패했을 때 오류를 던짐
          throw new Error('에러');
        }
      })
      .catch(error => {
        // 요청 실패 시 롤백
        alert('항목을 삭제하지 못했습니다.'); // 토스트 메시지
        // 오류 발생 시 이전 상태로 데이터 복구
        setData(currentData);
      });
  };

  return (
    <div>
      {data.map(item => (
        <div key={item.id}>
          {item.content}
          <button onClick={() => deleteItem(item.id)}>삭제</button>
        </div>
      ))}
    </div>
  );
}

export default OptimisticUpdateExample;

4. 적용결과

바로 적용되는 업데이트
에러 시 사용자가 인지할 수 있게 적절한 메시지를 띄워주자

 

수정 요청이 바로 적용되어 사용자에게 빠른 응답을 제공하고, 결과적으로 UX를 개선하였다.

또한 에러 시 사용자가 인지할 수 있게 적절한 메시지를 띄워주었다.

 

좋아요, 북마크 등 서비스 비즈니스에 큰 영향을 끼치지 않는 로직은 낙관적 업데이트 적용을 고려해 볼 만하다.