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

ZDF에서 오프라인 지원, 설치 가능, 어두운 모드와 같은 최신 기능을 갖춘 프로그레시브 웹 앱 (PWA)을 어떻게 만들었는지 알아보세요.

마틴 쉴레
마틴 쉴레
스콧 프리젠
스콧 프리젠

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

서비스 워커 추가

PWA의 주요 기능은 오프라인 지원입니다. ZDF의 경우 대부분의 어려운 작업은 다양한 캐싱 전략을 쉽게 지원할 수 있는 라이브러리와 노드 모듈 집합인 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는 공개적으로 홍보되지 않았지만 사용자 수가 꾸준히 증가하고 있습니다. 이 중 대부분은 Windows 10 사용자가 PWA를 검색하고 플랫폼별 앱처럼 설치할 수 있는 Microsoft Store에서 제공됩니다.

다음 단계

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