이 글을 동글에서 낙관적 업데이트를 도입하기까지의 과정을 담은 글입니다.
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를 개선하였다.
또한 에러 시 사용자가 인지할 수 있게 적절한 메시지를 띄워주었다.
좋아요, 북마크 등 서비스 비즈니스에 큰 영향을 끼치지 않는 로직은 낙관적 업데이트 적용을 고려해 볼 만하다.
'우아한테크코스 5기 프론트엔드' 카테고리의 다른 글
GitHub Actions를 이용해 gh-pages로 Storybook 배포하기 (0) | 2023.11.20 |
---|---|
반응형 스타일을 적용하여 다양한 기기에서 동글 서비스 제공하기 (0) | 2023.11.06 |
MSW 잘 사용하기: 유저가 보는 부분에 따라 데이터 쪼개기 (0) | 2023.10.15 |
[프로젝트 동글 최적화] 번들 사이즈의 25%를 차지하는 highlight.js 개선하기 (0) | 2023.09.12 |
[프로젝트 동글] 서비스 타겟 환경 및 브라우저 지원 범위 (0) | 2023.08.30 |