ZDF가 오프라인 모드와 어두운 모드로 동영상 PWA를 만든 방법

ZDF가 오프라인 지원, 설치 가능성, 어두운 모드와 같은 최신 기능을 갖춘 프로그레시브 웹 앱(PWA)을 만든 방법을 알아보세요.

Martin Schierle
Martin Schierle
Scott Friesen
Scott Friesen

방송사 ZDF는 프런트엔드 기술 스택을 재설계하는 것을 고려하면서 스트리밍 사이트 ZDFmediathek프로그레시브 웹 앱을 자세히 살펴보기로 결정했습니다. 개발 대행사인 Cellular는 ZDF의 플랫폼별 iOS 및 Android 앱과 동등한 웹 기반 환경을 구축하는 과제를 맡았습니다. PWA는 설치 가능, 오프라인 동영상 재생, 전환 애니메이션, 어두운 모드를 제공합니다.

서비스 워커 추가

PWA의 핵심 기능은 오프라인 지원입니다. ZDF의 경우 대부분의 까다로운 작업은 Workbox에서 수행합니다. Workbox는 다양한 캐싱 전략을 쉽게 지원할 수 있게 해 주는 라이브러리 및 노드 모듈 집합입니다. ZDF PWA는 TypeScript 및 React로 빌드되므로 create-react-app에 이미 빌드된 Workbox 라이브러리를 사용하여 정적 애셋을 미리 캐시합니다. 이렇게 하면 애플리케이션이 동적 콘텐츠(이 경우 동영상 및 메타데이터)를 오프라인에서 사용할 수 있도록 하는 데 집중할 수 있습니다.

기본 아이디어는 매우 간단합니다. 동영상을 가져와 IndexedDB에 blob으로 저장합니다. 그런 다음 재생 중에 온라인/오프라인 이벤트를 리슨하고 기기가 오프라인 상태가 되면 다운로드한 버전으로 전환합니다.

안타깝게도 상황이 조금 더 복잡해졌습니다. 프로젝트 요구사항 중 하나는 오프라인 지원을 제공하지 않는 공식 ZDF 웹 플레이어를 사용하는 것이었습니다. 플레이어는 콘텐츠 ID를 입력으로 받아 ZDF API와 통신하고 연결된 동영상을 재생합니다.

이때 웹의 가장 강력한 기능 중 하나인 서비스 워커가 유용합니다.

서비스 워커는 플레이어가 실행한 다양한 요청을 가로채 IndexedDB의 데이터로 응답할 수 있습니다. 이렇게 하면 플레이어의 코드를 한 줄도 변경하지 않고도 오프라인 기능이 투명하게 추가됩니다.

오프라인 동영상은 상당한 경향이 있으므로 그중에 실제로 기기에 저장할 수 있는 동영상이 얼마나 되는지가 중요한 질문입니다. 앱은 StorageManager API를 사용하여 사용 가능한 공간을 추정하고 공간이 부족할 경우 다운로드를 시작하기도 전에 사용자에게 알릴 수 있습니다. 안타깝게도 Safari는 이 API를 구현하는 브라우저 목록에 포함되어 있지 않으며 이 문서 작성 당시에는 다른 브라우저에서 할당량을 적용하는 방식에 관한 최신 정보가 충분하지 않았습니다. 따라서 팀은 다양한 기기에서 동작을 테스트하기 위한 소형 유틸리티를 작성했습니다. 이제 모든 세부정보를 요약하는 포괄적인 도움말이 있습니다.

맞춤 설치 메시지 추가

ZDF PWA는 맞춤 인앱 설치 흐름을 제공하며 사용자가 첫 번째 동영상을 다운로드하려고 할 때 바로 앱을 설치하라는 메시지를 표시합니다. 사용자가 앱을 오프라인에서 사용하겠다는 명확한 의도를 표현했으므로 이때 설치를 요청하는 것이 좋습니다.

설치 맞춤 초대입니다. 오프라인에서 시청하기 위해 동영상을 다운로드할 때 맞춤 설치 메시지가 트리거됨
오프라인 소비를 위해 동영상을 다운로드할 때 트리거되는 맞춤 설치 메시지

오프라인 페이지를 빌드하여 오프라인 저장 콘텐츠에 액세스

기기가 인터넷에 연결되어 있지 않고 사용자가 오프라인 모드에서 사용할 수 없는 페이지로 이동하면 이전에 오프라인 저장한 모든 동영상이 나열된 특수 페이지가 표시되거나(아직 콘텐츠를 오프라인 저장하지 않은 경우) 오프라인 기능에 관한 간단한 설명이 표시됩니다.

오프라인으로 시청할 수 있는 모든 콘텐츠를 보여주는 오프라인 페이지 오프라인으로 시청할 수 있는 콘텐츠가 없음을 보여주는 오프라인 페이지
오프라인으로 시청할 수 있는 모든 콘텐츠가 표시된 오프라인 페이지

적응형 기능에 프레임 로드 속도 사용

풍부한 사용자 환경을 제공하기 위해 ZDF PWA에는 사용자가 스크롤하거나 탐색할 때 발생하는 미묘한 전환이 포함되어 있습니다. 이러한 애니메이션은 보급형 기기에서 일반적으로 그 반대의 효과를 주며, 초당 60프레임으로 실행되지 않으면 앱이 느려지고 반응이 느려집니다. 이를 고려하여 앱은 requestAnimationFrame()를 통해 실제 프레임 속도를 측정하고 애플리케이션은 값이 특정 기준점 아래로 떨어지면 모든 애니메이션을 로드하고 사용 중지합니다.

const frameRate = new Promise(resolve => {
  let lastTick;
  const samples = [];

  function measure() {
    const tick = Date.now();
    if (lastTick) samples.push(tick - lastTick);
    lastTick = tick;
    if (samples.length < 20) requestAnimationFrame(measure);
    else {
      const avg = samples.reduce((a, b) => a + b) / samples.length;
      const fps = 1000 / avg;
      resolve(fps);
    }
  }
  measure();
});

이 측정값은 기기의 성능을 대략적으로 나타내며 각 부하에 따라 달라지지만 의사결정을 내리는 데는 유용했습니다. 사용 사례에 따라 개발자가 구현할 수 있는 적응형 로드의 다른 기법이 있습니다. 이 접근 방식의 한 가지 큰 장점은 모든 플랫폼에서 사용할 수 있다는 것입니다.

어두운 모드

최신 모바일 환경에서 인기 있는 기능은 어두운 모드입니다. 특히 조명이 어두운 환경에서 동영상을 시청할 때는 많은 사용자가 어두운 UI를 선호합니다. ZDF PWA는 사용자가 밝은 테마와 어두운 테마 간에 전환할 수 있는 스위치를 제공할 뿐만 아니라 OS 전체 색상 환경설정 변경에 반응합니다. 이렇게 하면 시간에 따라 테마를 변경하는 일정을 설정한 기기에서 앱의 모양이 자동으로 변경됩니다.

결과

새로운 프로그레시브 웹 앱은 2020년 3월에 공개 베타로 비공개 출시되었으며 이후 많은 긍정적인 의견을 받았습니다. 베타 단계가 계속되는 동안 PWA는 자체 임시 도메인에서 계속 실행됩니다. PWA가 공개적으로 홍보되지 않았음에도 사용자 수가 꾸준히 증가하고 있습니다. 이러한 PWA 중 다수는 Windows 10 사용자가 PWA를 검색하고 플랫폼별 앱처럼 설치할 수 있는 Microsoft 스토어에서 제공됩니다.

다음 단계

ZDF는 맞춤설정을 위한 로그인, 교차 기기 및 플랫폼 보기, 푸시 알림 등 PWA에 기능을 계속 추가할 계획입니다.