1. 소개
이 섹션은 비규범적입니다.
웹 애플리케이션은 종종 신뢰할 수 없는 네트워크(예: 휴대전화)와 불확실한 수명(브라우저가 종료되거나 사용자가 다른 곳으로 이동할 수 있음) 환경에서 실행됩니다. 이로 인해 웹 앱이 서버와 콘텐츠 및 상태를 동기화 상태로 유지하기가 어려워집니다.
이 API는 서버와 웹 앱 간의 콘텐츠 생성과 콘텐츠 동기화 사이의 시간을 줄이기 위해 설계되었습니다. 웹 앱이 주기적으로 상태와 데이터를 동기화하려는 의도를 원하는 최소 간격과 함께 등록할 수 있도록 함으로써 이를 실현합니다. 서비스 워커 이벤트를 통해 사용자 에이전트는 주기적으로 웹 앱이 네트워크 리소스를 다운로드하고 상태를 업데이트하도록 허용합니다.
이 API는 서비스 워커에 의존하므로, 이 API가 제공하는 기능은 보안 컨텍스트에서만 사용할 수 있습니다.
1.1. 예제
브라우징 컨텍스트(browsing context)에서 최소 간격을 하루로 하여 주기적 백그라운드 동기화를 등록하는 예:async function registerPeriodicNewsCheck() { const registration= await navigator. serviceWorker. ready; try { await registration. periodicSync. register( 'fetch-news' , { minInterval: 24 * 60 * 60 * 1000 , }); } catch { console. log( 'Periodic Sync could not be registered!' ); } }
서비스 워커(service worker) 내에서 periodicsync 이벤트에 반응하는 예:
self. addEventListener( 'periodicsync' , event=> { event. waitUntil( fetchAndCacheLatestNews()); });
위 예제에서 fetchAndCacheLatestNews는 개발자가 정의한 함수로, 서버에서 최신 뉴스 기사를 가져와 로컬에 저장합니다. 예를 들어 오프라인 사용을 위해
Cache
API를 사용할 수 있습니다.
2. 개념
주기적 동기화 등록에 대해 periodicsync 이벤트가 발생할 때, 해당 registration과 연관된 서비스 워커 등록의 origin에 대해 프레임 유형(frame type)이 "top-level",
"auxiliary" 또는 "nested"인 서비스 워커 클라이언트가 존재하지 않으면, 그 이벤트는 백그라운드에서 실행되는 것으로 간주됩니다.
3. 서비스 워커 등록에 대한 확장
서비스 워커 등록(service worker registration)은 추가로 다음을 가집니다:
-
활성 주기적 동기화 등록 (a map), 여기서 각 키는
DOMString이며, 각 항목은 periodic sync registration입니다. -
주기적 동기화 처리 큐, 초기값은 새 병렬 큐 시작의 결과입니다.
4. 구성
4.1. 주기적 동기화 등록
주기적 동기화 등록(periodic sync registration)은 다음으로 구성됩니다:
서비스 워커 등록, 이는 service worker registration입니다.
태그, 이는 DOMString입니다.
참고: Periodic Background Sync는 Background Sync와 네임스페이스를 공유하지 않으므로, 동일한 origin은 동일한 태그로 두 유형의 등록을 모두 가질 수 있습니다.
최소 간격 (long long), 주기적 동기화가 발생해야 하는 최소 간격(밀리초)을 지정하는 데 사용됩니다. minimum interval은 사용자 에이전트에 대한 제안입니다.
참고: 실제로 periodicsync 이벤트가 발생하는 간격은 반드시 이 값보다 크거나 같아야 합니다.
주기적 동기화 등록의 기준 시점(anchor time) (타임스탬프)은 이 periodicsync 이벤트가 이 주기적 동기화 등록에 대해 이전에 발생한 시점이거나 초기 등록 시점입니다.
주기적 동기화 등록의 상태는 "pending",
"firing", "suspended" 또는 "reregistered-while-firing" 중 하나이며, 초기값은
"pending"입니다.
4.2. 주기적 동기화 스케줄러
주기적 동기화 스케줄러(periodic sync scheduler)는 periodicsync 이벤트의 발생을 예약하는 역할을 합니다. 트리거에 응답하여 스케줄러는 적절한 미래 시점에 periodicsync 이벤트를 발생시키기 위해 지연된 처리를 예약하거나, 그러한 예약을 취소합니다.
스케줄러는 다음을 유지합니다:
원본(origin)에 대한 유효 최소 동기화 간격 origin (an origin)은 모든 origin에 대한 최소 주기적 동기화 간격에 사용자 에이전트가 정의한 원본별 추가 값을 더한 값입니다.
참고: 사용자 에이전트가 정의한 추가 값은 사용자가 해당 origin과 갖는 참여도(engagement)에 따라 달라질 수 있습니다. 이 값은 원본에 대한 유효 최소 동기화 간격이 호출될 때마다 달라질 수 있습니다.
스케줄러는 주기적 동기화 등록을 처리합니다.
참고: 브라우저는 리소스를 절약하기 위해 활성 주기적 동기화 등록이 없을 때 이 처리 루프를 일시 중단할 수 있습니다.
4.3. 상수
섹션 § 5 개인정보 보호 고려사항 및 § 6 자원 사용에서 권장한 바와 같이, 사용자 에이전트는 다음을 정의해야 합니다:
-
모든 origin에 대한 최소 주기적 동기화 간격, long long, 이는 특정 origin에 대해 발생할 수 있는 periodicsync 이벤트 사이의 최소 간격을 나타냅니다.
-
origin 간 최소 주기적 동기화 간격, long long, 이는 모든 origin에 걸쳐 periodicsync 이벤트 사이의 최소 간격을 나타냅니다.
origin 간 최소 주기적 동기화 간격은 모든 origin에 대한 최소 주기적 동기화 간격보다 크거나 같아야 합니다. 정의되지 않은 경우, 이 값들은 43200000(밀리초 단위의 12시간)으로 설정됩니다.
참고: 빈도에 대한 두 가지 제한이 필요한 이유는, 각 origin에 대해 모든 origin에 대한 최소 주기적 동기화 간격 제한을 준수하더라도 브라우저가 매우 자주 periodicsync 이벤트를 발생시킬 수 있기 때문입니다. 예를 들어 서로 다른 여러 origin에 많은 주기적 동기화 등록이 있는 경우에 발생할 수 있습니다. origin 간 최소 주기적 동기화 간격은 이러한 이벤트가 발생하는 전역적 상한을 보장합니다.
사용자 에이전트는 각 periodicsync 이벤트에 대해 허용되는 최대 재시도 횟수(숫자)를 정의할 수 있습니다. 이 값을 선택할 때, 사용자 에이전트는 최대 재시도 횟수를 시도하는 데 필요한 시간이 모든 origin에 대한 최소 주기적 동기화 간격보다 한 자릿수 작도록 보장해야 합니다. 정의되지 않은 경우, 이 값은 0입니다.
5. 개인정보 보호 고려사항
5.1. 권한
Periodic Background Sync는PermissionState
가 PermissionDescriptor
에 대해 name
이 "periodic-background-sync" 인 경우에만 사용할 수 있으며 해당 PermissionState가 granted
여야 합니다.
또한 사용자 에이전트는 사용자가 Periodic Background Sync를 비활성화할 수 있는 방법을 제공해야 합니다.
Periodic Background Sync가 비활성화된 경우, periodicsync 이벤트는 이 권한의 영향을 받는 주기적 동기화 등록
에 대해 발행되어서는 안 됩니다. (참조: § 7.2 권한 취소에 대응).
5.2. 위치 추적
백그라운드 상태(in the background)에서의 periodicsync 이벤트 내의 fetch 요청은 사용자가 페이지를 떠난 후 서버에 클라이언트의 IP 주소를 노출할 수 있습니다. 사용자 에이전트는 재시도 횟수와 periodicsync 이벤트의 지속 시간을 제한하여 웹사이트가 사용자의 위치를 추적할 수 있는 시간을 줄여야 합니다. 또한 사용자 에이전트는 특정 origin에 대해, 그리고 여러 origin에 걸쳐 periodicsync 이벤트의 빈도를 제한하여 지속적인 위치 추적을 억제해야 합니다.
5.3. 이력 누출
periodicsync 이벤트가 백그라운드에서 실행될 때의 fetch 요청은, 주기적 동기화 등록을 생성한 네트워크와 다른 네트워크 상의 미들박스(middlebox)에 클라이언트의 탐색 기록에 대한 정보를 드러낼 수 있습니다. 예를 들어, 클라이언트가 https://example.com 사이트를 방문하여 periodicsync 이벤트를 등록했지만, 구현 방식에 따라 사용자가 페이지에서 떠나고 네트워크를 변경한 후에야 이벤트가 발생할 수 있습니다. 새로운 네트워크상의 미들박스는 periodicsync 이벤트가 수행하는 fetch 요청을 볼 수 있습니다. 이 fetch 요청들은 HTTPS로 전송되므로 요청 내용 자체는 유출되지 않지만, 요청 대상과 도메인(예: DNS 조회 및 요청의 IP 주소)은 노출될 수 있습니다. 탐색 이력의 이러한 유출을 방지하기 위해, 사용자 에이전트는 periodicsync 이벤트를 주기적 동기화 등록이 이루어진 네트워크에서만 발생시키도록 선택할 수 있으며, 이는 동기화를 기회가 있을 때마다 수행하지 못하게 되어 사용성은 줄어들 수 있다는 점을 전제로 합니다.
6. 자원 사용
이 섹션은 비규범적입니다.
웹사이트는 periodicsync 이벤트를 처리할 때 네트워크에서 리소스를 다운로드할 가능성이 큽니다. 기본 운영 체제는 이러한 이벤트를 디스패치하기 위해 사용자 에이전트를 실행시키고, 이벤트 처리를 허용하기 위해 미리 정해진 기간 동안 에이전트를 깨어 있도록 할 수 있습니다. 이 둘 모두 배터리 소모를 초래합니다. 사용자 에이전트는 사용자가 페이지에서 떠났을 때 웹사이트의 자원 사용을 제한하기 위해 이러한 이벤트의 지속 시간과 빈도를 상한해야 합니다.
큰 리소스는 background fetch를 통해 BackgroundFetchManager
인터페이스로 등록하여 다운로드해야 합니다.
또한 사용자 에이전트는 origin에 대한 사용자 참여도(engagement)와 데이터 절약 모드(Data Saving Mode)와 같이 데이터 사용을 일시적으로 줄이려는 사용자의 표시를 고려하여 periodicsync 이벤트의 빈도를 조정해야 합니다.
7. 알고리즘
7.1. 주기적 동기화 등록 처리
사용자 에이전트가 시작될 때, 다음 단계를 병렬로 실행합니다:-
무한 루프 동안:
-
origin 간 최소 주기적 동기화 간격을 기다립니다.
-
firedPeriodicSync를 false로 둡니다.
-
firedPeriodicSync가 false인 동안:
-
사용자 에이전트가 정의한 일정 시간만큼 기다립니다.
참고: 이는 서로 다른 주기적 동기화 등록들을 한 번의 기기 웨이크업으로 묶어 동기화할 때 유용합니다.
-
온라인이 될 때까지 기다립니다.
-
각 service worker registration registration에 대해, 해당 등록이 unregistered가 아닌 경우, 다음 단계를 해당 registration의 주기적 동기화 처리 큐에 대기열에 추가합니다:
-
origin을 periodicSyncRegistration의 origin으로 정합니다.
-
만약 time of last fire[origin] + 원본에 대한 유효 최소 동기화 간격(origin)이 현재 시각보다 크면, 계속합니다.
-
registration의 활성 주기적 동기화 등록들 각각에 대해:
-
만약 periodicSyncRegistration의 기준 시점(anchor time) + periodicSyncRegistration의 minimum interval이 현재 시각보다 크면, 계속합니다.
-
firedPeriodicSync를 true로 설정합니다.
-
periodicsync 이벤트를 발생시킵니다 (periodicSyncRegistration에 대해).
-
-
-
7.2. 권한 취소에 대응
원본 origin에 대해 name
이 "periodic-background-sync"인 권한이 취소되는 것에 대응하려면, 사용자 에이전트는 다음 단계를 해당 주기적 동기화 처리 큐에 대기열에 추가해야 합니다:
-
해당 origin과 동일한 origin과 연관된 활성 주기적 동기화 등록 각각의 periodic sync registration registration에 대해:
-
registration을 active periodic sync registrations에서 제거합니다.
-
8. API 설명
8.1. ServiceWorkerGlobalScope 인터페이스에 대한 확장
partial interface ServiceWorkerGlobalScope {attribute EventHandler ; };onperiodicsync
8.2. ServiceWorkerRegistration 인터페이스에 대한 확장
ServiceWorkerRegistration/periodicSync
현재 엔진 중 하나에만 구현되어 있습니다.
Opera없음Edge80+
Edge (Legacy)없음IE없음
Firefox for Android없음iOS Safari없음Chrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile없음
[Exposed =(Window ,Worker )]partial interface ServiceWorkerRegistration {readonly attribute PeriodicSyncManager periodicSync ; };
ServiceWorkerRegistration
has a periodic sync manager (a PeriodicSyncManager).
The periodicSync
attribute’s getter must return the context object's
periodic sync manager, initially a
new PeriodicSyncManager
whose service worker registration is the
context object's service worker registration.
8.3.
PeriodicSyncManager
인터페이스
현재 엔진 중 하나에만 구현되어 있습니다.
Opera67+Edge80+
Edge (Legacy)없음IE없음
Firefox for Android없음iOS Safari없음Chrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
[Exposed =(Window ,Worker )]interface {PeriodicSyncManager Promise <undefined >register (DOMString ,tag optional BackgroundSyncOptions = {});options Promise <sequence <DOMString >>getTags ();Promise <undefined >unregister (DOMString ); };tag dictionary { [BackgroundSyncOptions EnforceRange ]unsigned long long = 0; };minInterval
PeriodicSyncManager
has a service worker registration (a service worker registration). 현재 엔진 중 하나에만 구현되어 있습니다.
Opera67+Edge80+
Edge (Legacy)없음IE없음
Firefox for Android없음iOS Safari없음Chrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
register(tag, options)
메서드는 호출될 때 새로운 promise
promise를 반환하고, 다음 단계들을 큐에 등록해야 합니다: 주기적 동기화 처리 큐에.
-
serviceWorkerRegistration을 서비스 워커 등록 객체로 둡니다. 이 객체는 context object의
PeriodicSyncManager와 연관됩니다. -
serviceWorkerRegistration의 active worker가 null이면, promise를 거부 promise를
InvalidStateError와 함께 반환하고 이 과정을 중단합니다. -
PermissionState가PermissionDescriptor에서name이"periodic-background-sync"일 때granted가 아니라면, promise를 거부 promise를NotAllowedError와 함께 반환하고 이 과정을 중단합니다. -
isBackground라는 boolean 변수를 true로 둡니다.
-
serviceWorkerRegistration의 origin에 대한 service worker client마다 다음을 수행합니다:
-
client의 frame type이 "
top-level" 또는 "auxiliary"이면 isBackground를 false로 설정합니다.
-
-
isBackground가 true라면, promise를 거부 promise를
InvalidAccessError와 함께 반환하고 이 과정을 중단합니다. -
currentRegistration을 serviceWorkerRegistration의 활성 주기적 동기화 등록(active periodic sync registrations) 중 tag가 tag와 같은 값을 가진 주기적 동기화 등록으로 지정하고, 없다면 null로 둡니다.
-
currentRegistration이 null이면:
-
newRegistration을 새로운 주기적 동기화 등록으로 만듭니다.
-
newRegistration의 tag를 tag로 설정합니다.
-
newRegistration의 minimum interval을 options의
minInterval값으로 설정합니다. -
newRegistration의 state를 "
pending"으로 설정합니다. -
newRegistration의 service worker registration을 serviceWorkerRegistration으로 설정합니다.
-
newRegistration의 anchor time을 현재 시점을 나타내는 타임스탬프로 설정합니다.
-
newRegistration을 serviceWorkerRegistration의 활성 주기적 동기화 등록에 추가합니다.
-
-
그 외의 경우(Else):
-
currentRegistration의 minimum interval이 options의
minInterval멤버와 다르다면:-
currentRegistration의 minimum interval을 options의
minInterval값으로 설정합니다.
-
-
그렇지 않고, currentRegistration의 state가 "
firing"이면, serviceWorkerRegistration의 state를 "reregistered-while-firing"으로 설정합니다.
-
현재 엔진 중 하나에만 구현되어 있습니다.
Opera67+Edge80+
Edge (Legacy)없음IE없음
Firefox for Android없음iOS Safari없음Chrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
getTags()
method when invoked, MUST return a new promise
promise and enqueue the following steps to the periodic sync
processing queue:
-
serviceWorkerRegistration을 PeriodicSyncManager와 연관된 서비스 워커 등록으로 정합니다.
-
currentTags를 새 list로 초기화합니다.
-
serviceWorkerRegistration의 active periodic sync registrations의 각 registration에 대해, append하여 registration의 tag를 currentTags에 추가합니다.
-
Resolve하여 promise를 currentTags로 완료합니다.
PeriodicSyncManager/unregister
현재 엔진 중 하나에만 구현되어 있습니다.
Opera67+Edge80+
Edge (Legacy)없음IE없음
Firefox for Android없음iOS Safari없음Chrome for Android80+Android WebView80+Samsung Internet13.0+Opera Mobile57+
unregister(tag)
method when invoked, MUST return a new promise
promise and enqueue the following steps to the periodic sync
processing queue:
-
serviceWorkerRegistration을 PeriodicSyncManager와 연관된 서비스 워커 등록으로 정합니다.
-
currentRegistration을 serviceWorkerRegistration의 active periodic sync registrations 중 periodic sync registration으로 하고, 그 tag가 tag와 같으면 사용하고, 그렇지 않으면 null로 둡니다.
-
만약 currentRegistration가 null이 아니면, serviceWorkerRegistration의 active periodic sync registrations에서 currentRegistration을 제거합니다.
-
promise를 Resolve합니다.
-
8.4. periodicsync 이벤트
PeriodicSyncEvent/PeriodicSyncEvent
현재 한 개 엔진에서만 지원됩니다.
Opera67+Edge80+
Edge (레거시)지원 안 함IE지원 안 함
Android용 Firefox지원 안 함iOS Safari지원 안 함Android용 Chrome80+Android WebView80+Samsung 인터넷13.0+Opera Mobile57+
현재 한 개 엔진에서만 지원됩니다.
Opera67+Edge80+
Edge (레거시)지원 안 함IE지원 안 함
Android용 Firefox지원 안 함iOS Safari지원 안 함Android용 Chrome80+Android WebView80+Samsung 인터넷13.0+Opera Mobile57+
dictionary :PeriodicSyncEventInit ExtendableEventInit {required DOMString ; }; [tag Exposed =ServiceWorker ]interface :PeriodicSyncEvent ExtendableEvent {(constructor DOMString ,type PeriodicSyncEventInit );init readonly attribute DOMString tag ; };
현재 한 개 엔진에서만 지원됩니다.
Opera67+Edge80+
Edge (레거시)지원 안 함IE지원 안 함
Android용 Firefox지원 안 함iOS Safari지원 안 함Android용 Chrome80+Android WebView80+Samsung 인터넷13.0+Opera Mobile57+
8.4.1. periodicsync 이벤트 발동
참고: 사용자 에이전트는PeriodicSyncEvent
의 수명 연장 및 실행 시간에 일반적인 ExtendableEvent
보다 더 엄격한 시간 제한을 적용할 수 있습니다. 특히, PeriodicSyncEvent
의 재시도는 현저하게 축소된 시간 제한이 적용될 수 있습니다.
-
serviceWorkerRegistration을 registration의 서비스 워커 등록으로 둡니다.
-
registration이 더 이상 serviceWorkerRegistration의 활성 주기적 동기화 등록에 포함되어 있지 않으면, 이 단계를 중단합니다.
-
retryCount를 0으로 설정합니다.
-
registration의 상태를 "
firing"으로 설정합니다. -
다음이 참일 동안:
-
continue를 false로 둡니다.
-
success를 false로 둡니다.
-
기능 이벤트 "
periodicsync"를PeriodicSyncEvent를 사용하여 serviceWorkerRegistration에서 tag를 registration의 tag로 지정해 발동합니다. dispatchedEvent라는ExtendableEvent가 발동된 periodicsync 이벤트를 나타내며, dispatchedEvent로 다음 단계를 수행합니다: -
waitUntilPromise를 모두 대기의 결과값으로, dispatchedEvent의 수명 확장 프로미스로 지정합니다.
-
이행될 때 waitUntilPromise는 다음 단계를 실행합니다:
-
success를 true로 둡니다.
-
continue를 true로 둡니다.
-
-
거부시 거부 시 waitUntilPromise는 다음 단계를 실행합니다:
-
continue를 true로 둡니다.
-
-
병렬로:
-
retryCount를 증가시킵니다.
-
retryCount에 따라 작은 백오프 시간만큼 대기합니다.
-