Post

낙관적 업데이트 vs 비관적 업데이트

낙관적 업데이트 vs 비관적 업데이트

✅비관적 업데이트

API 호출이 완료되고 데이터 또는 상태가 확인되면 UI를 업데이트하는 방식이다. 즉, 사용자 수정 요청서버에 수정 요청성공하면 화면 갱신의 과정을 통해 업데이트한다.

사용자는 서버에 요청하고 응답을 받을 때까지 UI의 변경을 기다려야하기 때문에 사용자 경험보다 중요한 데이터를 처리할 때 사용한다.

장점

  • 데이터 일관성: 서버의 응답을 받기 전까지 UI를 업데이트 하지 않기 때문
  • 간편한 오류 처리: 서버 응답에 따라 상태를 업데이트하고 오류를 처리할 수 있음
  • 사용자 혼란 감소: 응답을 바탕으로 실제 상태가 업데이트되기 때문에 혼란을 줄일 수 있음

단점

  • 사용자 경험 저하/지연된 피드백: 사용자는 서버의 응답을 받을 때까지 기다려야하기 때문에 사용자 경험이 떨어짐

예시

  1. 사용자가 삭제 버튼 클릭
  2. 사용자의 삭제 요청이 서버로 전송
  3. 서버는 삭제 성공 또는 실패에 대한 응답을 보냄
  4. 서버의 응답에 따라 콘텐츠 업데이트 하거나 오류 메세지 표시
1
2
3
4
5
6
7
deleteButton.addEventListener("click", function (event) {
  /* 서버에 삭제 요청 → response를 받기 → 그 결과에 따라 상태 업데이트 */
  deleteUser(api_url)
    .then((response) => response.json())
    .then((json) => pessimisticUserUpdate(json))
    .catch((error) => console.error(error));
});

✅낙관적 업데이트

작업이 성공할 것이라고 가정하고 API 요청이 완료되기 전에 UI가 새로운 데이터나 상태로 즉시 업데이트되는 방식이다. 즉 사용자 수정 요청화면 갱신서버에 수정 요청(실패 시 이전 상태로 돌리기)의 과정을 통해 업데이트한다.

이는 사용자 경험을 향상시키기 위해 나온 방식이며, 일관성과 신뢰성보다 사용자에게 즉각적인 피드백을 우선으로 한다.

장점

  • 사용자 경험: 상호작용이 빠르고 자연스러워져서 사용자의 만족도가 높아짐
  • 인지된 지연 시간 감소: 사용자 작업 이후 UI가 업데이트되므로 사용자는 응답 사이의 지연을 덜 인식함 → 더 빠른 성능에 대한 인식을 생성
  • 오프라인 및 낮은 연결성 지원: 연결이 낮은 시나리오에서도 잘 작동할 수 있음
  • 중단 없는 작업 흐름: 이미 성공을 가정하기 때문에 경고나 확인 대화를 적게 경험할 수 있음

단점

  • 데이터 일관성: 클라이언트가 성공할 것이라고 가정한 작업을 서버가 거부하면 해결해야 할 데이터 불일치나 충돌이 발생할 위험이 있음
  • 오류 처리 복잡성: 애플리케이션이 가정된 성공이 서버의 응답과 일치하지 않는 사례를 감지하고 처리해야 함
  • 사용자 혼란: 성공으로 가정하고, 나중에 서버 거부로 인해 되돌려진다면 사용자는 실제 결과가 일치하지 않기 때문에 혼란스러울 수 있음
  • 복잡한 동기화 논리: 성공적인 업데이트 및 롤백을 처리하기 위해 동기화 로직을 구현하는 것은 어려울 수 있음, 또한 버그 가능성이 높아질 수 있음
  • 보안 문제: 서버의 적절한 검증 없이 성공을 가정하면 잠재적으로 보안 취약성 또는 승인되지 않은 작업이 발생할 수 있음

예시

  1. 사용자가 삭제 버튼 클릭
  2. 콘텐츠 변경 상태 업데이트
  3. 사용자의 삭제 요청이 서버로 전송
  4. 서버는 실패할 경우 실패에 대한 응답을 보냄
  5. 실패에 대한 응답을 바탕으로 실패 메세지가 출력되고, 상태가 원래 상태로 변경됨
1
2
3
4
5
6
7
8
9
10
11
12
13
deleteButton.addEventListener("click", function (event) {
  // 사용자의 콘텐츠 변경
  optimisticallyUpdateUser();

  /* 서버에 삭제 요청 → 만약 실패한 경우 revertOptimisticChange()를 통해 원래 상태로 롤백 */
  deleteUser(api_url)
    .then((response) => response.json())
    .then((json) => console.log("user deleted successfully"))
    .catch((error) => {
      console.log("Something went wrong while deleting the    user");
      revertOptimisticChange();
    });
});

출처

This post is licensed under CC BY 4.0 by the author.