logo
PostsJavaScript동일 컨텍스트 간 상태 공유 (1)

동일 컨텍스트 간 상태 공유 (1)

이번 글에서는 동일 컨텍스트 간 상태 공유에 대해 알아보겠습니다.

우선, 컨텍스트가 무엇인지 간략하게 알아봅시다.

컨텍스트

컨텍스트는 사전적 정의로 문맥, 맥락 또는 상황을 의미합니다. 프로그래밍에서의 컨텍스트는 특정 작업이나 상태, 환경에 대한 정보를 캡슐화하는 것을 의미합니다.

자바스크립트에서는 실행 컨텍스트라는 개념이 있습니다.

실행 컨텍스트

실행 컨텍스트는 코드가 실행되는 환경을 말합니다.
모든 자바스크립트 코드는 실행 컨텍스트 안에서 실행됩니다. 예를 들어, 함수가 호출되면 그 함수의 실행 컨텍스트가 생성되며, 해당 함수에서 선언된 변수, 상위 스코프, this 값 등이 포함됩니다.

index.js
function example() {
  const localVar = 'I exist only in this context';
  console.log(localVar);
}
example();

위 코드에서 example 함수가 실행되면 새로운 실행 컨텍스트가 생성되고, 그 안에서만 localVar가 유효합니다.

브라우저 컨텍스트

브라우저에는 실행 컨텍스트와는 또 다른 의미로 브라우저 컨텍스트라는 개념이 존재합니다. MDN 에서는 이를 브라우징 맥락(browsing context) 으로 설명하고 있습니다.

브라우징 맥락은 브라우저가 Document를 표시하는 환경을 말합니다. 오늘날에는 보통 탭이지만, 브라우저 창이나 페이지 내의 프레임도 가능합니다.
각 브라우징 맥락은 특정 출처, 활성화된 문서의 출처, 그리고 표시했던 모든 문서의 방문 기록을 가집니다.

쉽게 말해, 브라우저의 탭 하나가 독립적인 브라우저 컨텍스트라고 볼 수 있습니다. 여러 탭이 동일한 웹 애플리케이션을 열었을 때, 이들은 독립적인 실행 환경을 가지며 서로의 상태를 직접 공유하지 않습니다.

자세한 내용은 이 문서(MDN | 브라우징 맥락)를 참고하시기 바랍니다.

컨텍스트 간 상태 공유

현대 웹 애플리케이션은 점점 더 복잡해지고, 여러 창이나 탭에서 동시 작업이 이루어지는 경우가 많습니다. 이러한 환경에서는 컨텍스트 간 상태 공유가 필수적입니다. 예를 들어, 동일한 사용자가 여러 탭에서 동일한 애플리케이션을 사용한다고 가정해 봅시다.

  • 드라이브 업로드 상태 공유: 한 탭에서 파일 업로드가 진행 중일 때, 다른 탭에서 해당 상태를 실시간으로 확인
  • 채팅 애플리케이션: 여러 창에서 메시지 수신 상태 동기화
  • 쇼핑몰 장바구니: 다른 탭에서도 동일한 장바구니 상태 유지

이러한 상황에서는 동일 컨텍스트 간 상태 공유가 필수적입니다. 하지만 브라우저의 탭은 서로 독립적인 컨텍스트를 가지므로, 직접 상태를 공유할 수 없습니다.

물론, 서버를 통해 상태를 동기화할 수 있지만, 실시간으로 동기화되는 상태를 유지하기 위해서는 추가적인 작업이 필요합니다. 또한 그렇게 매번 서버에 요청을 보내는 것은 몇 가지 방면에서 비효율적이라고 볼 수 있습니다.

문제 1) 서버 요청 비용

서버를 통한 상태 동기화는 서버의 리소스뿐만 아니라 금전적인 비용도 증가시킬 수 있습니다.
AWS, Azure와 같은 클라우드 서비스를 사용하는 경우 요청 수와 데이터 전송량에 따라 추가 비용이 발생합니다. 또한, 서버 요청이 많아지면 서버의 부하가 증가하고, 이는 응답 시간을 느리게 하거나 시스템 성능을 저하시킬 수 있습니다.

문제 2) 네트워크 지연

서버 요청은 네트워크를 통해 이루어지기 때문에, 다음과 같은 지연 문제가 발생할 수 있습니다.

  1. 물리적 거리: 클라이언트와 서버 간 물리적 거리가 멀수록 요청-응답 시간이 길어집니다. 이는 특히 글로벌 서비스를 운영할 때 문제가 됩니다.

  2. 네트워크 품질: 사용자의 네트워크 상태가 불안정하거나 느린 경우 요청 처리 속도가 떨어질 수 있습니다.

  3. 중복 요청: 동일한 상태를 확인하기 위해 여러 번의 요청을 보내는 경우, 네트워크 트래픽이 증가하고, 전체 시스템의 응답성이 저하될 수 있습니다.

문제 3) 실시간 동기화

컨텍스트 상태 공유가 없다면 일반적인 상황에서도 일정 주기마다 서버에 동기화 요청을 보내야 합니다. 이는 실시간성을 보장하기 어렵게 만들며, 사용자 경험을 저하시킬 수 있습니다.

예를 들어 10초에 한 번씩 서버에 요청을 보내는 경우, 사용자는 최대 10+@초의 지연을 경험할 수 있습니다. 여기서 @는 서버 응답 시간을 의미합니다.

💡

WebSocket을 사용하면 상태를 실시간으로 동기화할 수 있지만, 서버와의 연결을 유지하는 데에도 지속적인 리소스 소모가 발생합니다. 특히 다수의 클라이언트가 연결된 환경에서는 서버가 이를 관리하는 데 더 많은 리소스를 필요로 합니다.

문제 4) UX 저하

컨텍스트 간 상태가 공유되지 않으면 사용자는 동일한 작업을 여러 번 반복해야 하며, 이는 사용자 경험(UX)을 크게 저하시킬 수 있습니다.

예를 들어, 쇼핑몰 서비스를 사용한다고 가정해 보겠습니다.
사용자가 한 탭에서 장바구니에 상품을 추가한 후, 다른 탭에서 장바구니를 확인하려고 할 때 상태가 동기화되지 않는다면, 사용자는 다음 두 가지 중 하나를 선택해야 합니다.

  1. 장바구니에 추가한 상품을 다시 찾아 추가
    • 이는 시간과 노력을 불필요하게 소비하게 만듭니다.
    • 특히, 사용자가 어떤 상품을 추가했는지 기억하지 못하는 경우에는 더 큰 불편을 겪게 됩니다.
  2. 장바구니 페이지를 새로고침
    • 새로고침은 상태를 강제로 동기화하는 방법이지만, 페이지 로딩 시간이 추가로 소요됩니다.
    • 사용자는 이러한 과정에서 중단된 경험을 느끼며, 전체적인 만족도가 떨어질 수 있습니다.

기존 접근 방식의 한계

컨텍스트 간 상태를 공유하려는 기존 접근 방식에는 몇 가지 한계가 있습니다.

  • 로컬 스토리지(LocalStorage): 데이터는 저장되지만 이벤트 기반으로 상태를 동기화하지 않으므로 실시간성 부족.
  • 쿠키(Cookies): 클라이언트와 서버 간 동기화는 가능하지만, 브라우저 탭 간 직접적인 상태 공유에는 적합하지 않음.
  • 서버 기반 동기화: 지속적인 GET 요청이나 WebSocket 연결은 서버 리소스를 소모하고 네트워크 부하를 증가시킴.

결론

컨텍스트 간 상태 공유는 현대 웹 애플리케이션에서 더 이상 선택이 아닌 필수 요소입니다. 특히 실시간성과 데이터 일관성이 중요한 애플리케이션에서는 적절한 상태 공유 방식을 선택하는 것이 성공의 열쇠입니다. 다음 글에서는 이러한 문제를 해결할 수 있는 Broadcast Channel API에 대해 알아보겠습니다.