비활성 상태 재검증을 통해 최신 상태 유지

웹 앱을 제공할 때 즉시성과 최신성 사이의 균형을 이루는 데 도움이 되는 추가 도구입니다.

무엇이 배송되었나요?

stale-while-revalidate는 개발자가 즉시 캐시된 콘텐츠를 즉시 로드하는 것과 캐시된 콘텐츠의 업데이트가 나중에 사용되도록 하는 최신성 사이에서 균형을 맞추는 데 도움이 됩니다. 정기적으로 업데이트되는 서드 파티 웹 서비스 또는 라이브러리를 유지하거나 퍼스트 파티 애셋의 수명이 짧은 경향이 있다면 stale-while-revalidate가 기존 캐싱 정책에 유용할 수 있습니다.

Cache-Control 응답 헤더의 max-age와 함께 stale-while-revalidate를 설정하는 기능은 Chrome 75Firefox 68에서 제공됩니다.

stale-while-revalidate를 지원하지 않는 브라우저는 이 구성 값을 자동으로 무시하고 max-age를 사용합니다. 이 내용은 잠시 후에 설명합니다.

의미

stale-while-revalidate를 두 부분으로 분류해 보겠습니다. 캐시된 응답이 오래되었을 수 있다는 개념과 재검증 프로세스입니다.

첫째, 브라우저에서 캐시된 응답이 "오래된"지 여부를 어떻게 알 수 있습니까? stale-while-revalidate를 포함하는 Cache-Control 응답 헤더도 max-age를 포함해야 하며, max-age를 통해 지정된 시간(초)이 비활성을 결정합니다. max-age보다 최신의 캐시된 응답은 모두 새 응답으로 간주되며 이전에 캐시된 응답은 비활성으로 간주됩니다.

로컬로 캐시된 응답이 여전히 최신이면 이 응답을 그대로 사용하여 브라우저의 요청을 처리할 수 있습니다. stale-while-revalidate의 관점에서 이 시나리오에서는 할 일이 없습니다.

하지만 캐시된 응답이 오래된 경우 다른 연령 기반 확인이 수행됩니다. 즉, 캐시된 응답이 stale-while-revalidate 설정에서 제공하는 추가 기간 내에 경과되었는지 여부

비활성 응답의 기간이 이 기간에 속하는 경우 브라우저의 요청을 처리하는 데 사용됩니다. 동시에 캐시된 응답의 사용을 지연시키지 않는 방식으로 네트워크에 '재검증' 요청이 전송됩니다. 반환된 응답은 이전에 캐시된 응답과 동일한 정보를 포함하거나 다를 수 있습니다. 어느 쪽이든 네트워크 응답이 로컬에 저장되어 이전 캐시를 대체하고 향후 max-age 비교 중에 사용되는 '최신성' 타이머를 재설정합니다.

그러나 비활성 캐시된 응답이 오래되어 stale-while-revalidate 기간을 벗어나면 브라우저의 요청을 이행하지 않습니다. 대신 브라우저는 네트워크에서 응답을 검색하여 초기 요청을 처리하고 로컬 캐시를 새로운 응답으로 채우는 데 사용합니다.

실제 사례

다음은 현재 시간(보다 구체적으로는 매 시간 지난 분)을 반환하는 HTTP API의 간단한 예입니다.

이 시나리오에서 웹 서버는 HTTP 응답에 이 Cache-Control 헤더를 사용합니다.

Cache-Control: max-age=1, stale-while-revalidate=59

이 설정은 시간 요청이 다음 1초 이내에 반복되면 이전에 캐시된 값이 여전히 최신 상태로 유지되며 유효성 재검사 없이 그대로 사용된다는 것을 의미합니다.

1~60초 후에 요청이 반복되면 캐시된 값은 비활성 상태가 되지만 API 요청을 처리하는 데 사용됩니다. 동시에 나중에 사용할 수 있도록 캐시를 새 값으로 채우기 위한 재검증 요청이 '백그라운드에서' 이루어집니다.

요청이 60초 이상 반복되면 비활성 응답이 전혀 사용되지 않으며 브라우저 요청과 캐시 재검증 모두 네트워크에서 응답을 다시 받는 것에 따라 달라집니다.

다음은 이 세 가지 상태를 자세히 살펴보고 각 상태가 이 예에서 적용되는 기간입니다.

이전 섹션의 정보를 보여주는 다이어그램

일반적인 사용 사례는 무엇인가요?

'시간 후 몇 분' API 서비스에 대한 위의 예는 부자연스럽지만, 새로고침해야 하는 정보를 제공하지만 어느 정도의 비활성은 허용 가능한 서비스 등 예상되는 사용 사례를 보여줍니다.

덜 진솔한 예로는 현재 기상 조건에 관한 API 또는 지난 한 시간 동안 작성된 주요 뉴스 헤드라인이 있습니다.

일반적으로 알려진 간격으로 업데이트되고 여러 번 요청될 가능성이 높으며 해당 간격 내에서 정적인 응답은 max-age를 통한 단기 캐싱에 적합합니다. max-age 외에 stale-while-revalidate를 사용하면 네트워크 응답을 차단하지 않고 최신 콘텐츠가 있는 캐시에서 향후 요청을 처리할 가능성이 높아집니다.

서비스 워커와 어떻게 상호작용하는가?

stale-while-revalidate에 대해 들어본 적이 있다면 서비스 워커 내에서 사용되는 레시피의 컨텍스트일 가능성이 높습니다.

Cache-Control 헤더를 통해 비활성 상태 재검증을 사용하면 서비스 워커에서의 사용과 일부 유사점이 있으며, 최신 상태 장단점 및 최대 전체 기간에 대한 동일한 고려사항이 대부분 적용됩니다. 하지만 서비스 워커 기반 방식을 구현할지 아니면 Cache-Control 헤더 구성을 사용할지 결정할 때 고려해야 할 몇 가지 사항이 있습니다.

다음의 경우 서비스 워커 접근 방식을 사용하세요.

  • 이미 웹 앱에서 서비스 워커를 사용하고 있습니다.
  • 캐시의 콘텐츠를 세밀하게 제어해야 하며 가장 오래전에 사용된 만료 정책 등을 구현하려고 합니다. 이때 Workbox의 캐시 만료 모듈이 도움이 될 수 있습니다.
  • 재검증 단계 중에 백그라운드에서 비활성 응답이 변경되면 알림을 받고자 합니다. Workbox의 브로드캐스트 캐시 업데이트 모듈이 도움이 될 수 있습니다.
  • stale-while-revalidate 동작은 모든 최신 브라우저에 필요합니다.

다음과 같은 경우 Cache-Control 접근 방식을 사용합니다.

  • 웹 앱용 서비스 워커를 배포하고 유지보수하는 오버헤드를 처리하지 않습니다.
  • 브라우저의 자동 캐시 관리를 통해 로컬 캐시가 너무 커지지 않게 할 수 있습니다.
  • 현재 일부 최신 브라우저에서는 지원되지 않는 접근 방식을 사용하고 있습니다 (2019년 7월 기준, 향후 지원이 확대될 수 있음).

서비스 워커를 사용 중이고 Cache-Control 헤더를 통한 일부 응답에 stale-while-revalidate도 사용 설정한 경우 서비스 워커는 일반적으로 요청에 응답할 때 '최초'에 빠집니다. 서비스 워커가 응답하지 않기로 결정하거나 응답을 생성하는 중에 fetch()를 사용하여 네트워크 요청을 하는 경우 Cache-Control 헤더를 통해 구성된 동작이 결국 적용됩니다.

자세히 알아보기

사무엘 젤러의 히어로 이미지