응답이 벌써 왔다고? (feat. Optimistic Updates)

Zain·2025년 4월 12일

게임적인 요소가 가미된 펫과 나무 성장 기능을 개발하면서, 광고 참여 기반의 비즈니스 로직보다도 UX/UI 측면에서 즉각적인 클라이언트 상태 업데이트가 필요하다고 느꼈다.

Optimistic Update를 도입하여, 사용자의 입력에 대한 즉각적인 응답과 그 결과에 따른 안정적인 상태 업데이트를 구현하고자 한다.


1. Optimistic Updates 란?

Optimistic Update는 사용자의 액션에 대해 서버의 응답을 기다리지 않고, 클라이언트에서 먼저 상태를 변경해 보여주는 기법

“요청이 성공할 거라고 가정(optimistic) 하고, 먼저 반영하고 본다!”

  • 서버 응답을 기다리지 않고 먼저 UI에 반영하므로, 유저가 빠르게 반응을 체감할 수 있음.
  • 액션 → 반응 사이에 딜레이가 없으니 인터랙션이 자연스러움.
  • 특히 모바일 네트워크 환경에서 체감 속도 개선에 효과적.
    • 웹뷰로 개발된 어플리케이션, 대체적으로 모바일 사용자는 빠른 피드백에 익숙함.
      1초만 반응이 없으면 "앱이 멈췄나?"라고 느끼기 쉬움.

2. Optimistic Updates 도입

TanStack Query를 사용하지 않고 Action에서 직접 구현. (의존성을 최소화하는 것을 선호 ,,)

export async function confirmAdoptionComplete(pet) {
  	// catch에서 원본 상태 복구를 위함
    const originalPet = JSON.parse(JSON.stringify(pet))
    
    const optimisticState = {
        isAdopted: true,
        adoptedAt: null
    }
    setOptimisticPetState(pet, optimisticState)

    return ApiService().jsonPost(`/api/pets/pet/${pet.id}/confirm-adoption-complete`)
        .then(({ data }) => {
            return processApiResult(originalPet, data)
        }).catch((e)=>{
            // error 핸들링...
            setPets(originalPet)
        })
}


// optimistic update function
const setOptimisticPetState = (pet, optimisticState)=>{
    const optimisticPetState = {...pet, ...optimisticState}

    setPets(optimisticPetState)
}

클라이언트가 confirmAdoptionComplete 함수를 통해 입양 상태를 완료 처리하고자 할 때,
Optimistic Update를 사용하여 사용자에게 입양 완료 상태를 즉시 반영.
이후 서버 요청이 실패하면, catch 블록에서 UI를 원래 상태로 복구.

Optimistic Update를 도입하면서, 사용자에게 더 즉각적이고 자연스러운 피드백을 제공할 수 있었고,
전체적인 UX 흐름이 훨씬 매끄러워졌다.
비록 서버 응답과 실제 상태 사이에 일시적인 차이가 존재할 수 있지만, 신뢰할 수 있는 복구 로직과 함께라면 오히려 사용자 경험을 해치지 않으면서도 반응 속도를 끌어올릴 수 있다는 점에서 의미 있는 개선이었다.

profile
Vue, Laravel | TS, JS, PHP, MySQL

0개의 댓글