백그라운드 동기화 소개

Jake Archibald
Jake Archibald

백그라운드 동기화 사용자가 안정적인 상태가 될 때까지 작업을 연기할 수 있게 해주는 새로운 웹 API입니다. 연결을 제공합니다 이렇게 하면 사용자가 보내려는 것이 실제로 전송되도록 할 수 있습니다.

문제

인터넷은 시간 낭비하기 좋은 공간입니다. 인터넷에서 시간을 낭비하지 않는다면 고양이는 꽃을 싫어하고, 카멜레온이 거품을 좋아하고, 에릭 비델만90년대 후반의 퍼트 골프 선수라는 사실을 알지 못할 것입니다.

하지만 때로는 시간을 낭비하지 않으려는 경우가 있습니다. 원하는 사용자 다음과 같습니다.

  1. 휴대전화를 꺼냈습니다.
  2. 사소한 목표를 달성합니다.
  3. 휴대전화를 주머니에 넣어 다니세요.
  4. 수명을 다시 시작합니다.

안타깝게도 연결 불량으로 인해 이 환경은 자주 손상됩니다. 누구나 겪었을 겁니다. 흰색 화면이나 로딩 표시만 쳐다보고 있습니다. 포기하고 인생을 시작해야 한다는 것을 알고 있지만, 만일의 경우에 대비해 10초 더 시간을 내야 합니다. 10초 후에요? 없습니다.

하지만 지금 포기하는 이유는 무엇일까요? 이미 시간을 투자했으므로 아무것도 하지 않고 자리를 비우는 것은 낭비가 되지 않으므로 계속 기다려야 합니다. 이 시점에서 포기하고 싶지만 하지만 포기하는 순간은 기다리기만 했다면 모든 것이 로드되기 전 두 번째 순간이라는 것을 알고 있습니다.

서비스 워커는 캐시에서 콘텐츠를 제공하도록 하여 페이지 로드 부분을 해결합니다. 하지만 페이지가 무언가를 서버로 전송해야 하는 경우에는 어떻게 해야 할까요?

이때 사용자가 '보내기'를 누르면 완료될 때까지 스피너를 쳐다봐야 합니다 사용자가 다른 곳으로 이동하거나 탭을 닫으려고 하면 onbeforeunload를 사용하여 '아니요, 이 스피너를 더 봐야 합니다. 죄송합니다. 인터넷에 연결되어 있지 않으면 사용자에게 "죄송합니다. 나중에 다시 시도하셔야 합니다"라고 말합니다.

말도 안 돼. 백그라운드 동기화를 사용하면 더 효율적으로 할 수 있습니다.

해결 방법

다음 동영상은 그림 이모티콘 전용 채팅 데모인 Emojoy를 보여줍니다. 프로그레시브 웹 앱이며 오프라인 우선으로 작동합니다. 앱이 푸시 메시지와 알림을 사용하고 백그라운드 동기화를 사용합니다.

인터넷에 연결되어 있지 않을 때 사용자가 메시지를 보내려고 하면 다행히 인터넷에 연결되면 백그라운드에서 메시지가 전송됩니다.

2016년 3월부터 Chrome 버전 49 이상에서 백그라운드 동기화를 사용할 수 있습니다. 다음 단계에 따라 작업을 확인할 수 있습니다.

  1. Emojoy를 엽니다.
  2. 오프라인으로 전환합니다 (비행기 모드를 사용하거나 가까운 패러데이 케이지 방문).
  3. 메시지를 입력합니다.
  4. 홈 화면으로 돌아갑니다 (원하는 경우 탭이나 브라우저를 닫음).
  5. 인터넷에 연결하세요.
  6. 백그라운드에서 메시지가 전송됩니다.

이와 같이 백그라운드에서 전송할 수 있으면 성능이 향상됩니다. 앱은 메시지 전송에 크게 신경 쓸 필요가 없으므로 출력에 메시지를 즉시 추가할 수 있습니다.

백그라운드 동기화 요청 방법

진정한 확장 웹 스타일에서 이는 필요한 작업을 자유롭게 할 수 있는 하위 수준 기능입니다. 다음을 요청합니다. 사용자가 네트워크에 연결되면 시작되는 이벤트이며, 사용자가 인터넷에 연결되면 즉시 시작됩니다. 이미 연결되어 있습니다. 그런 다음 그 이벤트를 듣고 해야 합니다.

푸시 메시징과 마찬가지로 서비스 워커를 이벤트 대상으로 사용하므로 페이지가 열려 있지 않을 때도 작동할 수 있습니다. 시작하려면 페이지에서 동기화에 등록하세요.

// 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개의 동기화 이벤트를 개별적으로 사용하려는 경우 고유 태그만 사용하면 됩니다.

기본적인 작업을 수행하는 간단한 데모입니다. 동기화 이벤트를 사용하여 알림을 표시합니다.

백그라운드 동기화를 어떤 용도로 사용할 수 있나요?

페이지 수명 이후부터 중요한 데이터가 전송되도록 예약하는 데 사용하는 것이 가장 좋습니다. 채팅 메시지, 이메일, 문서 업데이트, 설정 변경, 사진 업로드 등 사용자가 다른 곳으로 이동하거나 탭을 닫는 경우에도 서버에 연결하고자 하는 모든 항목을 설정할 수 있습니다. 페이지에서 이러한 메일을 '보낼편지함'에 저장할 수 있습니다. 색인을 생성한 DB에 저장하고 서비스 워커가 이를 검색하고 보낼 것입니다.

하지만 그것을 사용하여 작은 비트의 데이터를 가져올 수도 있습니다...

또 다른 데모입니다!

이것은 페이지 로드 강화를 위해 만든 오프라인 위키백과 데모입니다. 이후 백그라운드 동기화 마법을 추가했습니다.

직접 해 보세요. Chrome 49 이상을 사용하고 있는지 확인한 후 다음 단계를 따르세요.

  1. Chrome과 같은 문서로 이동합니다.
  2. 오프라인으로 전환합니다 (비행기 모드를 사용하거나 저처럼 이용이 좋지 않은 이동통신사의 이용).
  3. 다른 자료로 연결되는 링크를 클릭합니다.
  4. 페이지를 로드할 수 없다는 메시지가 표시됩니다 (페이지가 로드되는 데 시간이 조금 걸리는 경우에도 표시됨).
  5. 알림에 동의합니다.
  6. 브라우저를 닫습니다.
  7. 온라인 전환
  8. 기사가 다운로드되고 캐시되어 볼 준비가 되면 알림을 받습니다.

사용자는 이 패턴을 사용하여 주머니에 휴대전화를 넣고 원하는 대로 휴대전화를 가지고 다니며, 원하는 물건을 가져왔을 때 알림을 받을 수 있습니다.

권한

보여드린 데모에서는 권한이 필요한 웹 알림을 사용하지만 백그라운드 동기화 자체는 사용하지 않습니다.

동기화 이벤트는 사용자가 사이트에 페이지를 열고 있는 동안 완료되는 경우가 많으므로 사용자 권한을 요구하면 사용자 경험이 저하될 수 있습니다. 대신 악용을 방지하기 위해 동기화가 등록되고 트리거될 수 있는 시점을 제한합니다. 예를 들면 다음과 같습니다.

  • 사용자에게 사이트 창이 열려 있는 경우에만 동기화 이벤트에 등록할 수 있습니다.
  • 이벤트 실행 시간은 제한되어 있으므로 x초마다 서버를 핑하거나 비트코인을 채굴하는 데 사용할 수 없습니다.

물론 실제 사용에 따라 이러한 제한이 완화되거나 축소될 수 있습니다.

점진적 개선

특히 Safari와 Edge가 아직 서비스 워커를 지원하지 않기 때문에 모든 브라우저에서 백그라운드 동기화를 지원하려면 시간이 걸릴 수 있습니다. 그러나 점진적인 개선을 통해 이 문제를 해결할 수 있습니다.

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 버전에 백그라운드 동기화를 제공하는 것을 목표로 하고 있습니다. 주기적 백그라운드 동기화를 사용하면 시간 간격, 배터리 상태 및 네트워크 상태로 인해 제한된 이벤트를 요청할 수 있습니다. 물론 이를 위해서는 사용자 권한이 필요하며, 이러한 이벤트가 언제 얼마나 자주 발생하는지는 브라우저에 달려 있습니다. 즉, 뉴스 사이트에서 매시간 동기화를 요청할 수 있지만 브라우저는 사용자가 해당 사이트를 07:00에만 읽었다는 것을 알고 있으므로 동기화는 매일 06:50에 실행됩니다. 이 아이디어는 일회성 동기화보다 조금 더 먼 방식이지만 곧 지원될 예정입니다.

우리는 안드로이드와 iOS의 성공적인 패턴을 웹으로 조금씩 도입하면서 동시에 훌륭한 웹의 요소를 유지하고 있습니다.