7. 응답은 기다리되, 경험은 즉각적으로 — UX 의사 결정 & 기능 설계

실제 응답 시간이 느리더라도, UI를 어떻게 보여주느냐에 따라 사용자가 느끼는 속도는 달라질 수 있다. 중요한 것은 서버의 응답을 무작정 기다리게 하는 것이 아니라, 지금 당장 보여줄 수 있는 정보를 먼저 보여주는 것이다.

Grabbin의 이미지 업로드와 링크 위젯을 예로 살펴보자.

이미지 업로드는 사용자가 이미지를 선택했을 때 업로드가 완료될 때 까지 아무것도 보여주지 않는 것은 다소 불편한 경험을 줄 수 있다. 그렇다고 이미지 영역을 skeleton으로 채우는 것이 최선일까?

skeleton은 아직 표시할 데이터가 없을 때 유용하다. 하지만 이미지처럼 클라이언트에서 즉시 미리보기를 만들 수 있는 경우에는 이야기가 다르다. 이때 skeleton을 보여주면 사용자는 여전히 "업로드가 끝나기를 기다리는 중"이라고 인식할 수 있다. 실제 업로드 속도뿐만 아니라, 이러한 대기 과정도 체감 속도에 영향을 주게 될 수 있겠다.

그래서 사용자가 이미지를 선택하는 즉시 blob URL을 생성해 미리보기를 보여준다. 서버 업로드가 완료될 때 까지 빈 화면이나 skeleton을 유지하지 않고, 사용자가 선택한 이미지를 바로 화면에 채우는 것이다. 업로드는 백그라운드에서 진행하고, 성공하면 blob URL을 실제 이미지 주소로 교체한다.

이 방식은 순서만 바꿨을 뿐이다. 업로드를 기다린 뒤 화면을 갱신 → 화면을 먼저 갱신하고 업로드를 기다림

순서만 바꿨을 뿐인데 사용자는 자신의 이미지가 이미 위젯에 추가되었다고 느끼고, 백그라운드에서 어떤 처리가 진행 중인지 의식하지 않아도 될 수 있겠다. 물론 업로드 실패에 대비한 오류 상태와 재시도 처리는 별도로 필요하고, 업로드가 완료되지 않았는데도 페이지를 새로고침 했을 때에 대한 처리도 필요하겠지만, 정상적인 흐름에서는 대기 시간을 UI에서 제거할 수 있다.

링크 위젯도 비슷한 문제를 파악했다. 사용자가 링크를 입력하면 서버는 해당 URL의 HTML을 가져와야 한다. 그 다음 og:title, og:description, og:image, favicon 같은 메타데이터를 찾아 링크 위젯을 완성한다.

문제는 이 작업의 응답 시점을 예측하기 어렵다는 점이다. 외부 사이트에 HTML을 요청하는 과정은 네트워크 상태의 영향을 받고 HTML 문서의 크기나 서버 응답 속도에 따라서도 시간이 달라진다. 어떤 링크는 빠르게 처리되지만, 어떤 링크는 꽤 오랫동안 응답하지 않을 수 있다.

이때 링크 위젯 전체를 skeleton으로 처리하면 이미지 업로드와 같은 문제가 발생한다. 실제로 화면에 표시할 수 있는 정보가 있는데도, 사용자는 서버가 응답할 때까지 기다리고 있다고 느끼게 되는 것이다.

하지만 링크에는 서버의 메타데이터를 기다리지 않고도 사용할 수 있는 정보가 이미 있다. 사용자가 입력한 URL 그 자체가 정보다. 우선 URL을 기반으로 임시 링크 위젯을 만든다. 제목은 URL에서 확인할 수 있는 주소 전체 또는 도메인으로 채우고, favicon은 도메인을 추출한 뒤 DuckDuckGo의 favicon 주소를 임시로 활용한다.

이렇게 하면 서버가 외부 HTML을 분석하는 동안에도 링크 아이템은 먼저 화면에 나타난다. 사용자는 링크가 추가되었다는 결과를 즉시 확인할 수 있다. (*물론 임시 데이터이기 때문에 약간은 갸우뚱할 수도 있겠다. 필자만 그럴수도?) 어쨌든 간에, 이후 서버가 실제 메타데이터를 반환하면 임시 제목, favicon, 설명, 이미지를 실제 응답 데이터로 교체한다.

이 방식은 실제 속도 자체를 줄이는 대신, 서버 응답을 기다리는 시간을 사용자가 인식하는 방식을 바꾸는 일종의 트릭이지만 효과는 꽤나 좋다고 생각한다.