Saiba como a ZDF criou um app da Web progressivo (PWA, na sigla em inglês) com recursos modernos, como suporte off-line, capacidade de instalação e modo escuro.
Quando a emissora ZDF estava pensando em redesenhar a pilha de tecnologia do front-end, ela decidiu dar uma olhada mais de perto nos apps da Web progressivos para o site de streaming ZDFmediathek. A agência de desenvolvimento Cellular aceitou o desafio de criar uma experiência baseada na Web que fosse equivalente aos apps para iOS e Android específicos da plataforma da ZDF. A PWA oferece capacidade de instalação, reprodução de vídeo off-line, animações de transição e modo escuro.
Como adicionar um service worker
Um recurso importante de uma PWA é o suporte off-line. Para ZDF, a maior parte do trabalho pesado é feita pelo Workbox, um conjunto de bibliotecas e módulos do Node que facilitam o suporte a diferentes estratégias de armazenamento em cache. O ZDF PWA é criado com TypeScript e React, portanto, usa a biblioteca Workbox já integrada ao create-react-app para armazenar em cache prévio os recursos estáticos. Isso permite que o aplicativo se concentre em disponibilizar o conteúdo dinâmico off-line, neste caso os vídeos e os metadados deles.
A ideia básica é bem simples: buscar o vídeo e armazená-lo como um blob no IndexedDB. Em seguida, durante a reprodução, detecte eventos on-line/off-line e mude para a versão salva quando o dispositivo ficar off-line.
Infelizmente, as coisas ficaram um pouco mais complexas. Um dos requisitos do projeto era usar o player da Web oficial do ZDF, que não oferece suporte off-line. O player usa um ID de conteúdo como entrada, se comunica com a API ZDF e reproduz o vídeo associado.
É aí que um dos recursos mais poderosos da Web vem para o resgate: service workers.
O service worker pode interceptar as várias solicitações feitas pelo player e responder com os dados do IndexedDB. Isso adiciona recursos off-line de maneira transparente sem precisar mudar uma única linha do código do player.
Como os vídeos off-line tendem a ser bastante grandes, uma grande questão é quantos deles podem ser armazenados em um dispositivo. Com a ajuda da API StorageManager, o app pode estimar o espaço disponível e informar ao usuário quando não há espaço suficiente antes mesmo de iniciar o download. Infelizmente, o Safari não está na lista de navegadores que implementam essa API, e, no momento da redação deste artigo, não havia muitas informações atualizadas sobre como outros navegadores aplicam cotas. Portanto, a equipe escreveu um pequeno utilitário para testar o comportamento em vários dispositivos. Já existe um artigo completo que resume todos os detalhes.
Como adicionar uma solicitação de instalação personalizada
A PWA do ZDF oferece um fluxo de instalação personalizado no app e solicita que os usuários instalem o app assim que quiserem fazer o download do primeiro vídeo. Esse é um bom momento para solicitar a instalação, porque o usuário expressou uma intenção clara de usar o app off-line.


Criar uma página off-line para acessar downloads
Quando o dispositivo não está conectado à Internet e o usuário navega para uma página que não está disponível no modo off-line, uma página especial é mostrada em vez disso, listando todos os vídeos que foram previamente transferidos por download ou (caso nenhum conteúdo tenha sido transferido ainda) uma breve explicação do recurso off-line.


Como usar a taxa de carregamento de frames para recursos adaptáveis
Para oferecer uma experiência de usuário rica, a PWA do ZDF inclui algumas transições sutis
que acontecem quando o usuário rola ou navega. Em dispositivos simples, essas
animações geralmente têm o efeito oposto e deixam o app lento e
menos responsivo se não forem executadas a 60 frames por segundo. Para levar isso em
consideração, o app mede a taxa de frames real usando requestAnimationFrame()
enquanto
o aplicativo carrega e desativa todas as animações quando o valor cai abaixo de um
determinado limite.
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();
});
Mesmo que essa medição forneça apenas uma indicação aproximada do desempenho do dispositivo e varie em cada carga, ela ainda é uma boa base para tomar decisões. Vale a pena mencionar que, dependendo do caso de uso, existem outras técnicas de carregamento adaptativo que os desenvolvedores podem implementar. Uma grande vantagem dessa abordagem é que ela está disponível em todas as plataformas.
Modo escuro
Um recurso popular para experiências modernas em dispositivos móveis é o modo escuro. Muitas pessoas preferem uma interface escura, principalmente quando estão assistindo vídeos em ambientes com pouca luz. A PWA do ZDF não apenas oferece uma chave que permite aos usuários alternar entre um tema claro e um escuro, como também reage às mudanças nas preferências de cores do SO. Dessa forma, o app vai mudar automaticamente a aparência em dispositivos que configuraram uma programação para mudar a base do tema de acordo com o horário do dia.
Resultados
O novo app da Web progressiva foi lançado silenciosamente como uma versão Beta pública em março de 2020 e recebeu muito feedback positivo desde então. Enquanto a fase Beta continua, a PWA ainda é executada no próprio domínio temporário. Embora a PWA não tenha sido promovida publicamente, o número de usuários está crescendo constantemente. Muitos deles são da Microsoft Store, que permite que os usuários do Windows 10 descubram PWAs e os instalem como apps específicos da plataforma.
A seguir
A ZDF planeja continuar adicionando recursos à PWA, incluindo login para personalização, visualização entre dispositivos e plataformas e notificações push.