앱과 유사한 환경을 위해 백그라운드에서 웹 앱의 데이터 동기화
다음과 같은 상황에 처한 적이 있나요?
- 연결이 불안정하거나 연결되지 않은 상태로 기차 또는 지하철을 이용하는 경우
- 동영상을 너무 많이 시청하여 이동통신사에서 제한함
- 대역폭이 수요를 따라가지 못하는 국가에 거주
그렇다면 웹에서 특정 작업을 수행할 때 답답함을 느꼈을 것이며, 이러한 시나리오에서 플랫폼별 앱이 더 나은 경우가 많은 이유가 궁금했을 것입니다. 플랫폼별 앱은 뉴스 기사나 날씨 정보와 같은 최신 콘텐츠를 미리 가져올 수 있습니다. 지하철에 네트워크가 없더라도 뉴스를 읽을 수 있습니다.
주기적 백그라운드 동기화를 사용하면 웹 애플리케이션이 백그라운드에서 데이터를 주기적으로 동기화하여 웹 앱이 플랫폼별 앱의 동작에 더 가까워집니다.
직접 해 보기
DevTools Tips는 Periodic Background Sync API를 사용하는 PWA입니다. 개발자 도구 도움말 PWA는 매일 새로운 개발자 도구 도움말을 가져와 캐시에 저장하므로 사용자가 온라인 상태인지 여부와 관계없이 다음에 앱을 열 때 도움말에 액세스할 수 있습니다. Periodic Background Sync API를 사용하려면 앱을 설치해야 합니다.
GitHub의 소스 코드로 이동합니다. 특히 앱은 registerPeriodicSync()
함수에서 주기적 동기화를 등록합니다. 서비스 워커 코드는 앱이 periodicsync
이벤트를 리슨하는 곳입니다.
개념 및 사용
주기적인 백그라운드 동기화를 사용하면 프로그레시브 웹 앱이나 서비스 워커 지원 페이지가 실행될 때 최신 콘텐츠를 표시할 수 있습니다. 앱이나 페이지가 사용되지 않을 때 백그라운드에서 데이터를 다운로드하여 이 작업을 실행합니다. 이렇게 하면 앱의 콘텐츠가 실행 후 표시되는 동안 새로고침되지 않습니다. 또한 새로고침 전에 앱에서 콘텐츠 스피너가 표시되지 않도록 합니다.
주기적인 백그라운드 동기화가 없으면 웹 앱은 대체 방법을 사용하여 데이터를 다운로드해야 합니다. 일반적인 예는 푸시 알림을 사용하여 서비스 워커를 절전 모드에서 해제하는 것입니다. '새 데이터 사용 가능'과 같은 메시지로 인해 사용자가 중단됩니다. 데이터 업데이트는 기본적으로 부작용입니다. 중대한 속보와 같이 정말 중요한 업데이트의 경우 푸시 알림을 사용할 수 있습니다.
주기적 백그라운드 동기화는 백그라운드 동기화와 혼동될 수 있습니다. 이름은 비슷하지만 사용 사례는 다릅니다. 무엇보다도 백그라운드 동기화는 이전 요청이 실패한 경우 서버에 데이터를 다시 전송하는 데 가장 일반적으로 사용됩니다.
사용자 참여도 올바르게 설정하기
주기적인 백그라운드 동기화가 잘못 실행되면 사용자의 리소스가 낭비될 수 있습니다. Chrome에서는 이 기능을 출시하기 전에 시험 기간을 거쳐 올바른지 확인했습니다. 이 섹션에서는 이 기능을 최대한 유용하게 만들기 위해 Chrome에서 내린 몇 가지 설계 결정을 설명합니다.
Chrome에서 내린 첫 번째 설계 결정은 웹 앱이 사용자가 기기에 설치하고 별도의 애플리케이션으로 실행한 후에만 주기적인 백그라운드 동기화를 사용할 수 있다는 것입니다. 주기적 백그라운드 동기화는 Chrome의 일반 탭 컨텍스트에서 사용할 수 없습니다.
또한 Chrome에서는 사용하지 않거나 거의 사용하지 않는 웹 앱이 배터리나 데이터를 무상으로 소비하는 것을 원하지 않으므로 개발자가 사용자에게 가치를 제공하여 획득해야 하는 주기적인 백그라운드 동기화를 설계했습니다. 구체적으로 Chrome은 사이트 참여도 점수(about://site-engagement/
)를 사용하여 특정 웹 앱에 대해 주기적인 백그라운드 동기화가 발생할 수 있는지와 그 빈도를 결정합니다. 즉, 참여도 점수가 0보다 크지 않으면 periodicsync
이벤트가 전혀 발생하지 않으며, 참여도 점수 값은 periodicsync
이벤트가 발생하는 빈도에 영향을 미칩니다. 이렇게 하면 백그라운드에서 동기화되는 앱이 활발하게 사용 중인 앱만 됩니다.
주기적 백그라운드 동기화는 인기 플랫폼의 기존 API 및 관행과 유사한 점이 있습니다. 예를 들어 일회성 백그라운드 동기화와 푸시 알림을 사용하면 사용자가 페이지를 닫은 후에도 웹 앱의 로직이 서비스 워커를 통해 조금 더 오래 유지될 수 있습니다. 대부분의 플랫폼에서 사용자는 중요한 업데이트, 콘텐츠 미리 가져오기, 데이터 동기화와 같은 작업을 위해 백그라운드에서 주기적으로 네트워크에 액세스하는 앱을 설치하는 것이 일반적입니다. 마찬가지로 주기적인 백그라운드 동기화는 웹 앱의 로직 수명을 연장하여 한 번에 몇 분 동안 정기적으로 실행되도록 합니다.
브라우저에서 제한 없이 이러한 상황이 자주 발생하도록 허용하면 개인 정보 보호 문제가 발생할 수 있습니다. Chrome에서 주기적 백그라운드 동기화의 위험을 해결한 방법은 다음과 같습니다.
- 백그라운드 동기화 활동은 기기가 이전에 연결한 네트워크에서만 발생합니다. 신뢰할 수 있는 당사자가 운영하는 네트워크에만 연결하는 것이 좋습니다.
- 모든 인터넷 통신과 마찬가지로 주기적인 백그라운드 동기화는 클라이언트의 IP 주소, 클라이언트가 통신하는 서버, 서버 이름을 표시합니다. 앱이 포그라운드에 있을 때만 동기화하는 경우와 거의 비슷한 수준으로 노출을 줄이기 위해 브라우저는 앱의 백그라운드 동기화 빈도를 사용자가 해당 앱을 사용하는 빈도에 맞춰 제한합니다. 사용자가 앱과 자주 상호작용하지 않으면 주기적인 백그라운드 동기화가 트리거되지 않습니다. 이는 플랫폼별 앱의 현재 상태보다 순 개선입니다.
언제 사용할 수 있나요?
사용 규칙은 브라우저마다 다릅니다. 앞서 설명한 내용을 요약하면 Chrome에서는 주기적 백그라운드 동기화에 다음 요구사항을 적용합니다.
- 특정 사용자 참여 점수입니다.
- 이전에 사용한 네트워크가 있는지 여부입니다.
동기화 시점은 개발자가 제어하지 않습니다. 동기화 빈도는 앱 사용 빈도와 일치합니다. (플랫폼별 앱은 이렇게 하지 않습니다.) 또한 기기의 전원 및 연결 상태도 고려합니다.
언제 사용해야 하나요?
서비스 워커가 periodicsync
이벤트를 처리하기 위해 절전 모드에서 해제되면 데이터를 요청할 기회가 있지만 그렇게 할 의무는 없습니다. 이벤트를 처리할 때 네트워크 상태와 사용 가능한 저장소를 고려하고 이에 따라 다양한 양의 데이터를 다운로드해야 합니다. 다음 리소스를 참고하세요.
권한
서비스 워커가 설치된 후 Permissions API를 사용하여 periodic-background-sync
를 쿼리합니다. 이 작업은 창 또는 서비스 워커 컨텍스트에서 실행할 수 있습니다.
const status = await navigator.permissions.query({
name: 'periodic-background-sync',
});
if (status.state === 'granted') {
// Periodic background sync can be used.
} else {
// Periodic background sync cannot be used.
}
주기적 동기화 등록
이미 언급했듯이 주기적 백그라운드 동기화에는 서비스 워커가 필요합니다. ServiceWorkerRegistration.periodicSync
를 사용하여 PeriodicSyncManager
를 검색하고 register()
를 호출합니다. 등록에는 태그와 최소 동기화 간격 (minInterval
)이 모두 필요합니다. 태그는 등록된 동기화를 식별하므로 여러 동기화를 등록할 수 있습니다. 다음 예시에서 태그 이름은 'content-sync'
이고 minInterval
은 하루입니다.
const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
try {
await registration.periodicSync.register('content-sync', {
// An interval of one day.
minInterval: 24 * 60 * 60 * 1000,
});
} catch (error) {
// Periodic background sync cannot be used.
}
}
등록 확인
periodicSync.getTags()
를 호출하여 등록 태그 배열을 가져옵니다. 다음 예에서는 태그 이름을 사용하여 캐시 업데이트가 활성 상태인지 확인하여 다시 업데이트하지 않습니다.
const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
const tags = await registration.periodicSync.getTags();
// Only update content if sync isn't set up.
if (!tags.includes('content-sync')) {
updateContentOnPageLoad();
}
} else {
// If periodic background sync isn't supported, always update.
updateContentOnPageLoad();
}
getTags()
를 사용하여 웹 앱의 설정 페이지에 활성 등록 목록을 표시하여 사용자가 특정 유형의 업데이트를 사용 설정하거나 사용 중지할 수 있습니다.
주기적 백그라운드 동기화 이벤트에 응답
정기적인 백그라운드 동기화 이벤트에 응답하려면 서비스 워커에 periodicsync
이벤트 핸들러를 추가하세요. 이 함수에 전달된 event
객체에는 등록 중에 사용된 값과 일치하는 tag
매개변수가 포함됩니다. 예를 들어 주기적 백그라운드 동기화가 'content-sync'
이름으로 등록된 경우 event.tag
은 'content-sync'
이 됩니다.
self.addEventListener('periodicsync', (event) => {
if (event.tag === 'content-sync') {
// See the "Think before you sync" section for
// checks you could perform before syncing.
event.waitUntil(syncContent());
}
// Other logic for different tags as needed.
});
동기화 등록 취소
등록된 동기화를 종료하려면 등록 취소하려는 동기화 이름과 함께 periodicSync.unregister()
을 호출합니다.
const registration = await navigator.serviceWorker.ready;
if ('periodicSync' in registration) {
await registration.periodicSync.unregister('content-sync');
}
인터페이스
다음은 Periodic Background Sync API에서 제공하는 인터페이스를 간략하게 설명한 것입니다.
PeriodicSyncEvent
. 브라우저가 선택한 시간에ServiceWorkerGlobalScope.onperiodicsync
이벤트 핸들러에 전달됩니다.PeriodicSyncManager
. 주기적 동기화를 등록 및 등록 취소하고 등록된 동기화에 태그를 제공합니다. ServiceWorkerRegistration.periodicSync 속성에서 이 클래스의 인스턴스를 가져옵니다.ServiceWorkerGlobalScope.onperiodicsync
:PeriodicSyncEvent
를 수신하는 핸들러를 등록합니다.ServiceWorkerRegistration.periodicSync
.PeriodicSyncManager
에 대한 참조를 반환합니다.
예
다음 섹션에서는 주기적 백그라운드 동기화 API를 사용하는 몇 가지 예를 보여줍니다.
콘텐츠 업데이트
다음 예에서는 주기적인 백그라운드 동기화를 사용하여 뉴스 사이트나 블로그의 최신 기사를 다운로드하고 캐시합니다. 동기화 유형을 나타내는 태그 이름 ('update-articles'
)을 확인합니다. updateArticles()
호출은 기사가 다운로드되고 저장되기 전에 서비스 워커가 종료되지 않도록 event.waitUntil()
로 래핑됩니다.
async function updateArticles() {
const articlesCache = await caches.open('articles');
await articlesCache.add('/api/articles');
}
self.addEventListener('periodicsync', (event) => {
if (event.tag === 'update-articles') {
event.waitUntil(updateArticles());
}
});
기존 웹 앱에 주기적 백그라운드 동기화 추가
이 변경사항 세트는 기존 PWA에 주기적 백그라운드 동기화를 추가하는 데 필요했습니다. 이 예시에는 웹 앱의 주기적인 백그라운드 동기화 상태를 설명하는 유용한 로깅 문이 포함되어 있습니다.
주기적 백그라운드 동기화 API 디버그
로컬에서 테스트하는 동안 주기적인 백그라운드 동기화의 엔드 투 엔드 뷰를 가져오는 것은 어려울 수 있습니다. 활성 등록, 대략적인 동기화 간격, 과거 동기화 이벤트 로그에 관한 정보는 웹 앱의 동작을 디버깅할 때 유용한 컨텍스트를 제공합니다. 다행히 Chrome DevTools의 실험용 기능을 통해 이 모든 정보를 확인할 수 있습니다.
로컬 활동 기록
DevTools의 주기적 백그라운드 동기화 섹션은 주기적 백그라운드 동기화 수명 주기의 주요 이벤트(동기화 등록, 백그라운드 동기화 실행, 등록 취소)를 중심으로 구성됩니다. 이러한 이벤트에 관한 정보를 확인하려면 녹화 시작을 클릭합니다.

기록하는 동안 이벤트에 해당하는 항목이 DevTools에 표시되며 각 항목에 대해 컨텍스트와 메타데이터가 기록됩니다.

녹화 기능을 한 번 사용 설정하면 최대 3일 동안 사용 설정된 상태로 유지되므로 DevTools에서 몇 시간 후에 발생할 수 있는 백그라운드 동기화에 관한 로컬 디버깅 정보를 캡처할 수 있습니다.
이벤트 시뮬레이션
백그라운드 활동을 기록하는 것이 유용할 수 있지만, 정상적인 주기로 이벤트가 발생할 때까지 기다리지 않고 periodicsync
핸들러를 즉시 테스트하고 싶을 때도 있습니다.
Chrome DevTools의 애플리케이션 패널에 있는 서비스 워커 섹션을 사용하여 이 작업을 수행할 수 있습니다. 주기적 동기화 필드를 사용하면 사용할 이벤트의 태그를 제공하고 원하는 만큼 여러 번 트리거할 수 있습니다.

DevTools 인터페이스 사용
DevTools Application 패널에 Periodic Background Sync 섹션이 표시됩니다.
