일부 웹 사이트는 결과를 알 수 있습니다 예를 들면 다음과 같습니다.
- 페이지가 서비스 워커에게 프리페치가 사용되므로 사용자가 해당 문서나 페이지의 하위 리소스가 이미 캐시에 있는 경우, 훨씬 빠르게 탐색할 수 있습니다.
- 이 페이지는 서비스 워커에게 일련의 주요 기사를 검색하고 캐시하여 오프라인으로 사용할 수 있습니다.
이러한 유형의 중요하지 않은 작업을 서비스 워커에 위임하면 사용자 상호작용에 응답하는 등 좀 더 긴급한 작업을 더 잘 처리하기 위한 기본 스레드입니다.
이 가이드에서는 페이지에서 일방 커뮤니케이션 기법을 구현하여 표준 브라우저 API와 Workbox 라이브러리를 사용하여 서비스 워커를 구현할 수 있습니다. 우리는 이러한 유형의 명령적 캐싱으로 사용할 수 있습니다.
프로덕션 케이스
1-800-Flowers.com은 다음을 통해 서비스 워커로 명령적 캐싱 (미리 가져오기)을 구현했습니다.
postMessage()
를 눌러
카테고리 페이지의 상위 항목 을 사용하여 제품 세부정보 페이지로의 후속 탐색 속도를 높입니다.
다음과 같이 혼합된 접근 방식을 사용하여 미리 가져올 항목을 결정합니다.
- 페이지 로드 시 팀은 서비스 워커에게 상위 9개 항목에 대한 JSON 데이터를 검색하도록 요청합니다. 결과 응답 객체를 캐시에 추가합니다.
- 나머지 항목에서
mouseover
이벤트가 될 수 있으므로 사용자가 항목 위로 커서를 이동하면 '수요' 시 리소스 가져오기를 트리거할 수 있습니다.
Cache API를 사용하여 JSON을 저장합니다. 응답:
<ph type="x-smartling-placeholder">사용자가 항목을 클릭하면 이와 관련된 JSON 데이터를 캐시에서 가져올 수 있습니다. 네트워크에 이동하지 않아도 탐색이 더 빨라집니다.
Workbox 사용
Workbox를 사용하면 간편하게
서비스 워커: workbox-window
패키지를 통한 모듈 집합
창 컨텍스트에서 실행되도록 의도된 것입니다. 다른 Workbox 패키지를 보완합니다.
서비스 워커에서 실행되는 작업을 보여줍니다
페이지를 서비스 워커와 통신하려면 먼저 등록된 서비스 워커:
const wb = new Workbox('/sw.js');
wb.register();
그런 다음 메시지를 가져오는 번거로움 없이 선언적으로 메시지를 직접 보낼 수 있습니다. 기본 커뮤니케이션 API를 고려하거나, 등록, 활성화 확인,
wb.messageSW({"type": "PREFETCH", "payload": {"urls": ["/data1.json", "data2.json"]}}); });
서비스 워커는 message
핸들러를 구현하여
이 메시지를 들을 수 있습니다. 선택적으로 응답을 반환할 수 있지만, 이와 같은 경우에는
필요하지 않습니다.
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'PREFETCH') {
// do something
}
});
브라우저 API 사용
Workbox 라이브러리가 요구사항을 충족하기에 충분하지 않다면 다음과 같은 방법으로 window to service를 구현할 수 있습니다. 작업자 통신을 지원합니다
postMessage API 페이지에서 서비스 워커로의 단방향 통신 메커니즘을 설정하는 데 사용할 수 있습니다.
페이지는
postMessage()
서비스 워커 인터페이스:
navigator.serviceWorker.controller.postMessage({
type: 'MSG_ID',
payload: 'some data to perform the task',
});
서비스 워커는 message
핸들러를 구현하여
이 메시지를 들을 수 있습니다.
self.addEventListener('message', (event) => {
if (event.data && event.data.type === MSG_ID) {
// do something
}
});
{type : 'MSG_ID'}
속성은 필수는 아니지만 페이지에서 다음 작업을 실행하도록 허용하는 한 가지 방법입니다.
서비스 워커에 다른 유형의 명령을 보냅니다 (즉, '미리 가져오기' vs. '지우기 위해').
스토리지'). 서비스 워커는 이 플래그를 기반으로 다른 실행 경로로 분기할 수 있습니다.
작업이 성공하면 사용자는 이점을 얻을 수 있지만 그렇지 않은 경우 기본 사용자 플로우가 변경되지는 않습니다. 예를 들어 1-800-Flowers.com이 사전 캐시를 시도하는 경우 페이지는 서비스 워커가 성공했는지 여부를 알 필요가 없습니다. 포함되어 있으면 사용자가 더 빠르게 탐색할 수 있습니다. 그렇지 않은 경우에도 페이지가 새 페이지로 이동해야 합니다. 시간이 조금 더 걸릴 것 같습니다.
간단한 미리 가져오기의 예
명령적 캐싱의 가장 일반적인 적용 분야 중 하나는 미리 가져오기입니다. 미리 가져오기는 리소스를 할당하여 탐색 속도를 높일 수 있습니다.
사이트에서 미리 가져오기를 구현하는 방법에는 여러 가지가 있습니다.
- 페이지에서 링크 미리 가져오기 태그 사용: 리소스는
5분 동안 브라우저 캐시, 그 후에는 리소스에 대한 일반
Cache-Control
규칙이 적용됨 적용됩니다. - 서비스의 런타임 캐싱 전략으로 이전 기법 보완 worker를 사용하여 미리 가져오기의 전체 기간을 연장합니다. 리소스를 이 한도를 초과할 수 없습니다.
문서 미리 가져오기와 같이 비교적 간단한 미리 가져오기 시나리오나 특정 자산 (JS, CSS 등)를 사용하는 것이 가장 좋습니다.
추가 로직이 필요한 경우(예: 미리 가져오기 리소스(JSON 파일 또는 페이지)를 내부 URL을 가져오려면 이 작업을 전부 서비스 워커를 지원합니다
이러한 유형의 작업을 서비스 워커에 위임하면 다음과 같은 이점이 있습니다.
- 가져오기 및 가져오기 후 처리의 부담을 덜어줍니다 (다음에 도입될 예정). 두 번째 대화목록에 추가합니다. 이를 통해 기본 스레드가 더 중요한 작업을 처리할 수 있도록 예를 들어 사용자 상호작용에 응답하는 등의 작업을 수행해야 합니다
- 여러 클라이언트 (예: 탭)가 공통 기능을 재사용할 수 있도록 허용하고 서비스를 동시에 호출할 수 있습니다.
제품 세부정보 페이지 미리 가져오기
다음에서 postMessage()
처음 사용
캐시할 URL 배열을 전달합니다.
navigator.serviceWorker.controller.postMessage({
type: 'PREFETCH',
payload: {
urls: [
'www.exmaple.com/apis/data_1.json',
'www.exmaple.com/apis/data_2.json',
],
},
});
서비스 워커에서 message
핸들러를 구현하여
모든 활성 탭에서 보내는 메시지를 가로채서 처리합니다.
addEventListener('message', (event) => {
let data = event.data;
if (data && data.type === 'PREFETCH') {
let urls = data.payload.urls;
for (let i in urls) {
fetchAsync(urls[i]);
}
}
});
이전 코드에서는 fetchAsync()
라는 작은 도우미 함수를 도입하여
각각에 대한 가져오기 요청을 실행합니다.
async function fetchAsync(url) {
// await response of fetch call
let prefetched = await fetch(url);
// (optionally) cache resources in the service worker storage
}
응답을 얻으면 리소스의 캐싱 헤더를 사용할 수 있습니다. 많은 경우
그러나 제품 세부정보 페이지와 마찬가지로 리소스는 캐시되지 않습니다. 즉,
no-cache
의 Cache-control
헤더). 이러한 경우 다음을 실행하여 이 동작을 재정의할 수 있습니다.
서비스 워커 캐시에 가져온 리소스를
저장하지 않습니다 이렇게 하면
사용할 수 있습니다.
JSON 데이터 그 이상
서버 엔드포인트에서 JSON 데이터를 가져오면 다른 URL도 포함되는 경우가 많습니다. 이 첫 번째 레벨과 연결된 이미지 또는 기타 엔드포인트 데이터와 같이 미리 가져올 만한 가치가 있는 데이터를 수집하는 데 사용됩니다
이 예에서 반환된 JSON 데이터가 식료품 쇼핑 사이트의 정보라고 가정해 보겠습니다.
{
"productName": "banana",
"productPic": "https://cdn.example.com/product_images/banana.jpeg",
"unitPrice": "1.99"
}
제품 목록을 반복하고 히어로 이미지를 캐시하도록 fetchAsync()
코드를 수정합니다.
각각:
async function fetchAsync(url, postProcess) {
// await response of fetch call
let prefetched = await fetch(url);
//(optionally) cache resource in the service worker cache
// carry out the post fetch process if supplied
if (postProcess) {
await postProcess(prefetched);
}
}
async function postProcess(prefetched) {
let productJson = await prefetched.json();
if (productJson && productJson.product_pic) {
fetchAsync(productJson.product_pic);
}
}
404와 같은 상황에서 이 코드에 예외 처리를 추가할 수 있습니다. 그러나 서비스 워커를 사용하여 미리 가져오는 것의 장점은 많은 양의 데이터가 없어도 실패할 수 있다는 것입니다. 페이지의 기본 스레드에 적용됩니다. 또한 미리 가져온 콘텐츠를 후처리하여 유연성을 높이고 미리 가져온 데이터와 있습니다. 원하는 대로 자유롭게 결정할 수 있습니다.
결론
이 도움말에서는 페이지와 서비스 간의 단방향 통신의 일반적인 사용 사례를 다루었습니다. worker: 명령적 캐싱. 여기서 설명하는 예는 다음 설명 중 한 가지 방법을 다른 사용 사례에도 동일한 접근 방식을 적용할 수 있습니다. 오프라인 소비, 북마크 등을 위해 주문형으로 인기 기사를 캐시합니다.
페이지 및 서비스 워커 통신의 더 많은 패턴을 보려면 다음을 참조하십시오.
- 브로드캐스트 업데이트: 서비스 워커에서 페이지를 호출하여 (예: 새로운 버전의 웹 앱을 사용할 수 있는 경우))을 알릴 수 있습니다.
- 양방향 통신: 작업을 서비스 워커 (예: 다운로드) 진행 상황에 대해 페이지에 계속 알려야 합니다.