서비스 워커 배포에 대한 기대치

서비스 워커를 배포하면 웹사이트 동작이 예상치 못한 방식으로 변경될 수 있습니다. Workbox를 사용하면 서비스 워커를 쉽게 작성하고 배포할 수 있으므로 배포된 후 서비스 워커가 웹사이트에 미치는 일부 영향을 쉽게 놓칠 수 있습니다.

그렇다고 Workbox를 사용한다고 해서 결과가 좋지 않은 것은 아닙니다. 단지 Workbox가 제공하는 편의성으로 인해 서비스 워커를 배포할 때 어떤 문제가 발생하는지 모를 때 더 쉽게 함정에 빠질 수 있다는 것을 의미합니다.

사전 캐싱 문제

사전 캐싱은 이전에 이 문서에서 다루었으며 관행이 역효과를 일으킬 수 있는 방법을 완전히 다루지는 않습니다. 너무 많은 애셋에 사전 캐싱을 적용하거나 페이지에서 중요 애셋 로드를 완료하기 전에 서비스 워커가 등록되면 문제가 발생할 수 있습니다.

workbox-webpack-plugin의 기본 동작은 서비스 워커가 생성된 애셋을 자동으로 사전 캐시하도록 지시하는 것이므로 채택 장벽이 낮기 때문에 이를 놓치기 쉬운 방식으로 문제가 될 수 있습니다.

터미널 출력
workbox-webpack-plugin.의 터미널 출력 이 예시에서는 기본적으로 현재 프로젝트의 애셋 14개를 사전 캐시하여 총 352KB입니다.

설치 중에 서비스 워커가 애셋을 사전 캐시하면 하나 이상의 네트워크 요청이 동시에 시작됩니다. 따라서 타이밍이 올바르지 않으면 사용자 환경에 문제가 될 수 있습니다. 타이밍이 정확하더라도 사전 캐시된 애셋의 양이 어떤 식으로든 제한되지 않으면 여전히 데이터 낭비가 될 수 있습니다.

적절한 타이밍에

서비스 워커가 무언가를 사전 캐시하는 경우 서비스 워커가 등록된 시간이 중요합니다. 서비스 워커는 인라인 <script> 요소를 사용하여 등록되는 경우가 많습니다. 즉, 페이지의 중요 애셋이 로드되기 전에 HTML 파서가 서비스 워커 등록 코드를 발견할 수 있습니다.

이것은 문제입니다. 서비스 워커는 최악의 경우에도 성능 중립적이어야 하며 성능을 악화시키지 않는 것이 좋습니다. 사용자에게 혜택을 제공하고 페이지의 load 이벤트가 실행될 때 서비스 워커를 등록합니다. 이렇게 하면 사전 캐싱이 페이지의 중요한 애셋을 로드하는 데 방해가 될 가능성이 줄어듭니다. 따라서 나중에까지 필요하지 않을 수도 있는 애셋에 대한 네트워크 요청과 경합하지 않고도 페이지의 상호작용이 더 빨라질 수 있습니다.

데이터 사용량 고려

타이밍에 관계없이 사전 캐싱에는 네트워크 요청 디스패치가 포함됩니다. 사전 캐시할 애셋 매니페스트를 신중하게 선별하지 않으면 낭비가 될 수 있습니다.

데이터 낭비는 사전 캐싱의 잠재적인 단점이지만 모든 사람이 빠른 인터넷이나 무제한 데이터 요금제에 액세스할 수 있는 것은 아닙니다. 사전 캐싱을 수행할 때는 비용이 많이 드는 가정을 하기보다는 대용량 자산을 잘라내고 런타임 캐싱을 사용하여 캡처하는 것이 좋습니다.

서비스 워커 시작 시 네트워크 요청이 지연될 수 있음

서비스 워커는 웹사이트 코드의 나머지 부분과 별도의 프로세스에서 실행됩니다. 이 프로세스는 자주 시작되고 중지됩니다. 서비스 워커가 비활성화된 후 가져오기 이벤트를 처리해야 하는 경우 브라우저는 먼저 서비스 워커를 시작하는 데 시간을 할애해야 합니다. 요청이 처리되기 전에 발생하는 이러한 추가 오버헤드는 네트워크 대신 캐시에서 응답을 제공할 때의 이점에 비해 작습니다.

캐시에서 제공할 수 없고 네트워크로 이동해야 하는 전략을 사용하는 경우(특히 탐색 요청을 처리할 때) 부팅 시간에 따라 항상 약간의 지연이 추가됩니다. 기기 기능 또는 CPU 압력에 따라 서비스 워커 부팅 속도가 느려 탐색 요청에서 현저한 지연이 발생할 수 있습니다. 이러한 지연을 인지하지 못한 채 서비스 워커를 배포하면 사용자가 의도치 않은 성능 저하를 경험할 수 있습니다.

이 문제는 Navigation 미리 로드로 해결되었지만 아직 모든 브라우저에서 지원되지는 않습니다. 하지만 사용을 고려할 때는 이 문서의 후반부에서 다룹니다.

캐시 우선 전략의 역효과

캐시를 먼저 참조하거나 캐시 참조하는 캐싱 전략은 오프라인 액세스와 성능 모두에 적합합니다. 하지만 일부 특정 사례에서 문제가 발생하기도 합니다.

버전이 지정되지 않은 정적 애셋의 런타임 캐싱

Bundler는 일반적으로 파일 이름에 콘텐츠 기반 해시를 사용하여 정적 애셋의 버전을 지정합니다 (예: styles.a4edf38c.css). 정적 애셋에 대해 캐시를 먼저 확인하고 페이지 마크업에 네트워크 우선 전략을 사용하는 캐싱 전략을 사용하는 서비스 워커에서는 항상 네트워크에서 검색되는 마크업에서 업데이트된 애셋을 참조하므로 캐싱 문제가 발생하지 않습니다.

이러한 전략을 사용하여 버전이 지정되지 않은 정적 애셋이 런타임 중에 캐시되는 상황에서 문제가 발생합니다. 웹사이트의 기능이 app.js에서 제공되고 캐시 우선 런타임 전략이 사용되는 경우 나중에 파일 이름을 변경하지 않고 app.js가 업데이트되며, 처음에 캐시된 버전은 업데이트되지 않고 캐시에서 계속 제공됩니다.

해결책은 재검증 중 네트워크 우선 또는 비활성 상태 재검증과 같은 업데이트를 위해 네트워크에 참조하는 전략을 사용하는 것입니다. 또는 Workbox의 사전 캐싱 로직이 이를 최신 상태로 유지하므로 빌드 도구가 이러한 애셋의 사전 캐시 매니페스트를 생성할 수 있습니다.

그럼에도 불구하고 애셋 이름의 해시 또는 쿼리 문자열에 정적 애셋의 버전을 관리하는 것이 좋습니다. 이렇게 하면 정적 애셋에 캐시 우선 런타임 전략을 사용하는 서비스 워커에서 오래된 애셋 문제를 방지할 수 있습니다.

저장 용량 한도

서비스 워커 업데이트는 수시로 출시되며, 업데이트가 롤아웃되면 일반적으로 만료된 이름을 가진 이전 캐시는 새 서비스 워커가 활성화되는 동안 잘립니다.

그러나 일부 서비스 워커 반복은 오래 지속되거나 새 업데이트에서 캐시 이름이 업데이트되지 않을 수 있습니다. 이 경우 업데이트가 롤아웃될 때 오래된 정적 애셋이 캐시에 쌓일 수 있습니다. 브라우저에서 스토리지 할당량을 설정하며 한도는 다를 수 있습니다. 이들에게 주의를 기울여야 할 이유가 있습니다.

Workbox는 이러한 문제를 효과적으로 완화하지만, 여전히 스토리지 할당량을 초과할 수 있습니다. 작업 상자 만료 모듈을 사용하여 캐시를 더 세밀하게 제어할 수 있습니다.

두려워하지 마세요

서비스 워커를 배포하는 것은 결코 간단한 일이 아닙니다. 하지만 Workbox에 서비스 워커를 배포할 때 수반되는 사항에 대해 약간의 계획과 마음가짐을 가졌다면 그다지 어렵지 않은 일이 될 것입니다. 계속 진행하면서 이 문서는 이러한 우려사항을 신중히 다루고 해결하는 데 도움이 될 것입니다.