게시일: 2015년 12월 8일
백그라운드 동기화는 사용자가 안정적인 연결을 확보할 때까지 작업을 지연할 수 있는 웹 API입니다. 이렇게 하면 가능한 한 빨리 사용자가 원하는 파일을 전송할 수 있도록 지원할 수 있습니다.
문제
인터넷은 시간을 낭비하기에 좋은 곳입니다. 인터넷에서 시간을 낭비하지 않았다면 고양이가 꽃을 싫어한다거나 카멜레온이 비누방울을 좋아한다는 사실, 에릭 비델만이 1990년대 후반 퍼트퍼트 골프 영웅이라는 사실을 알지 못했을 것입니다.
하지만 때로는 시간을 낭비하고 싶지 않을 때도 있습니다. 이상적인 사용자 환경은 다음과 같습니다.
- 휴대전화가 주머니에 있지 않음
- 사소한 목표를 달성합니다.
- 휴대전화를 주머니에 넣습니다.
- 일상으로 돌아가세요.
하지만 연결 상태가 좋지 않으면 이러한 경험이 자주 중단됩니다. 다들 그런 경험이 있지요. 흰색 화면이나 스피너를 응시하고 있습니다. 포기하고 일상생활을 해야 한다는 것을 알지만 혹시나 하는 마음에 10초 더 기다립니다. 10초가 지난 후에는 어떻게 되나요? 없습니다.
하지만 지금 포기하면 안 됩니다. 이미 시간을 투자했으므로 아무것도 얻지 못하고 떠나는 것은 낭비이므로 계속 기다립니다. 이쯤 되면 포기하고 싶어지지만, 포기하는 순간 조금만 더 기다렸다면 모든 항목이 로드되었을 것이라는 것을 알고 있습니다.
서비스 워커는 캐시에서 콘텐츠를 제공할 수 있도록 하여 페이지 로드 부분을 해결합니다. 하지만 페이지에서 서버로 무언가를 전송해야 하는 경우는 어떨까요?
현재 사용자가 메시지에서 '보내기'를 누르면 메시지가 전송될 때까지 스피너를 응시해야 합니다. 사용자가 다른 곳으로 이동하거나 탭을 닫으려고 하면 onbeforeunload를 사용하여 '아니요, 이 스피너를 좀 더 응시해야 합니다. 미안해'라고 말합니다. 사용자가 연결되어 있지 않으면 '죄송합니다. 나중에 다시 시도해 주세요.'라고 안내합니다.
백그라운드 동기화를 사용하면 더 나은 결과를 얻을 수 있습니다.
해결 방법
다음 동영상은 그림 이모티콘 전용 채팅 데모인 Emojoy를 보여줍니다. 프로그레시브 웹 앱이며 오프라인 우선으로 작동합니다. 앱은 푸시 메시지와 알림을 사용하고 백그라운드 동기화를 사용합니다.
연결이 없는 상태에서 사용자가 메시지를 보내려고 하면 연결이 설정된 후 백그라운드에서 메시지가 전송됩니다.
이와 같이 백그라운드에서 전송할 수 있으면 인식되는 성능도 개선됩니다. 앱은 메시지 전송에 대해 그렇게 큰 문제를 만들 필요가 없으므로 출력을 바로 추가할 수 있습니다.
백그라운드 동기화는 Chrome 49부터 사용할 수 있습니다.
백그라운드 동기화를 요청하는 방법
진정한 확장 가능한 웹 스타일로, 이는 필요한 작업을 자유롭게 실행할 수 있는 하위 수준 기능입니다. 사용자가 연결되어 있을 때 이벤트가 발생하도록 요청합니다. 사용자가 이미 연결되어 있다면 즉시 발생합니다. 그런 다음 해당 이벤트를 수신 대기하고 필요한 작업을 실행합니다.
푸시 메시지와 마찬가지로 서비스 워커를 이벤트 타겟으로 사용하여 페이지가 열려 있지 않을 때도 작동할 수 있습니다. 시작하려면 페이지에서 동기화를 등록하세요.
// Register your service worker:
navigator.serviceWorker.register('/sw.js');
// Then later, request a one-off sync:
navigator.serviceWorker.ready.then(function(swRegistration) {
return swRegistration.sync.register('myFirstSync');
});
```
Then listen for the event in `/sw.js`:
```js
self.addEventListener('sync', function(event) {
if (event.tag == 'myFirstSync') {
event.waitUntil(doSomeStuff());
}
});
이상입니다 doSomeStuff()는 시도 중인 작업의 성공 또는 실패를 나타내는 프라미스를 반환해야 합니다. 프라미스가 이행되면 동기화가 완료됩니다.
실패하면 다시 시도하도록 다른 동기화가 예약됩니다. 동기화 재시도도 연결을 기다리고 지수 백오프를 사용합니다.
동기화의 태그 이름 ('myFirstSync')은 지정된 동기화에 대해 고유해야 합니다. 대기 중인 동기화와 동일한 태그를 사용하여 동기화를 등록하면 기존 동기화와 병합됩니다. 즉, 사용자가 메시지를 보낼 때마다 '아웃박스 지우기' 동기화를 등록할 수 있지만 오프라인 상태에서 메시지를 5개 보내면 온라인 상태가 되었을 때 동기화가 한 번만 실행됩니다. 5개의 개별 동기화 이벤트를 가져오려면 고유한 태그를 사용하세요.
동기화 이벤트를 사용하여 알림을 표시하는 데모를 확인하세요.
백그라운드 동기화에 사용
페이지 수명 이상으로 중요한 데이터 전송을 예약하는 데 사용하는 것이 좋습니다. 사용자가 다른 곳으로 이동하거나 탭을 닫더라도 서버에 도달해야 하는 채팅 메시지, 이메일, 문서 업데이트, 설정 변경, 사진 업로드 또는 콘텐츠 페이지는 이러한 데이터를 indexedDB의 '아웃박스' 저장소에 저장할 수 있고 서비스 워커는 이를 검색하여 전송합니다.
하지만 작은 데이터 비트를 가져오는 데 사용할 수도 있습니다.
오프라인 위키백과 데모
페이지 로드 속도 향상을 위해 만든 오프라인 위키백과 데모입니다. 이후 백그라운드 동기화 기능을 추가했습니다.
직접 사용해 보세요.
- 브라우저를 이 탭에 열어 두세요.
- 비행기 모드를 사용하거나 Wi-Fi를 사용 중지하여 오프라인 상태로 전환합니다.
- 다른 도움말 링크를 클릭합니다.
- 페이지를 로드할 수 없다는 메시지가 표시됩니다 (페이지를 로드하는 데 시간이 걸리는 경우에도 표시됨).
- 알림에 동의합니다.
- 브라우저를 닫습니다.
- 온라인 전환
- 기사가 다운로드되고 캐시되어 볼 수 있게 되면 알림을 받습니다.
이 패턴을 사용하면 사용자는 휴대전화를 주머니에 넣고 생활할 수 있으며, 원하는 항목이 가져와지면 휴대전화에서 알림을 보냅니다.
권한
제가 보여드린 데모에서는 권한이 필요한 웹 알림을 사용하지만 백그라운드 동기화 자체에는 권한이 필요하지 않습니다.
동기화 이벤트는 사용자가 사이트 페이지를 열어 둔 상태에서 완료되는 경우가 많으므로 사용자 권한을 요구하면 환경이 좋지 않습니다. 대신 악용을 방지하기 위해 동기화가 등록되고 트리거될 수 있는 시기를 제한하고 있습니다. 예를 들면 다음과 같습니다.
- 사용자가 사이트 창을 열어 둔 경우에만 동기화 이벤트를 등록할 수 있습니다.
- 이벤트 실행 시간은 제한되어 있으므로 x초마다 서버를 핑하거나 비트코인을 채굴하는 등의 용도로 사용할 수 없습니다.
물론 이러한 제한은 실제 사용량에 따라 완화되거나 강화될 수 있습니다.
점진적 개선
백그라운드 동기화가 기준이 될 때까지는 다음과 같이 점진적 개선으로 사용할 수 있습니다.
if ('serviceWorker' in navigator && 'SyncManager' in window) {
navigator.serviceWorker.ready.then(function(reg) {
return reg.sync.register('tag-name');
}).catch(function() {
// system was unable to register for a sync,
// this could be an OS-level restriction
postDataFromThePage();
});
} else {
// serviceworker/sync not supported
postDataFromThePage();
}
서비스 워커나 백그라운드 동기화를 사용할 수 없는 경우 오늘과 마찬가지로 페이지의 콘텐츠를 게시하면 됩니다.
사용자의 연결 상태가 양호한 것으로 보이더라도 백그라운드 동기화를 사용하는 것이 좋습니다. 데이터 전송 중에 탐색 및 탭 닫기를 방지할 수 있기 때문입니다.
미래의 업무 환경의 기반,
Google은 변형인 '주기적 백그라운드 동기화'를 개발하면서 2016년 상반기에 안정적인 버전의 Chrome에 백그라운드 동기화를 출시하는 것을 목표로 하고 있습니다. 주기적인 백그라운드 동기화를 사용하면 시간 간격, 배터리 상태, 네트워크 상태로 제한된 이벤트를 요청할 수 있습니다. 물론 사용자 권한이 필요하며 이러한 이벤트가 발생하는 시점과 빈도는 브라우저에 따라 달라집니다. 즉, 뉴스 사이트에서 매시간 동기화를 요청할 수 있지만 브라우저에서 사용자가 오전 7시에만 해당 사이트를 읽는다는 것을 알고 있다면 동기화는 매일 오전 6시 50분에 실행됩니다. 이 아이디어는 일회성 동기화보다 조금 더 먼 미래에 구현될 예정입니다.
Google은 웹의 장점을 유지하면서 Android와 iOS의 성공적인 패턴을 웹에 조금씩 도입하고 있습니다.