Siga o Papai Noel como um PWA

Acessar o site

Resumo

O Siga o Papai Noel foi rapidamente atualizado para um Progressive Web App off-line nas festas de fim de ano de 2016, em parte graças ao nosso design de cenário atual.

Resultados

  • O Papai Noel é um App Web Progressivo (PWA) compatível com adição à tela inicial (ATHS) e off-line
  • 10% das sessões qualificadas começaram pelo ícone do ATHS
  • 75% dos usuários ofereceram suporte nativo a elementos personalizados e shadow DOM, duas partes principais dos componentes da Web
  • Pontuação de 81 no Lighthouse
  • Off-line, por meio da API Service Worker, está vinculado ao carregamento lento para armazenar apenas as cenas visitadas em cache e fazer o upgrade silencioso em novas versões.

Contexto

O Siga o Papai Noel é uma tradição de fim de ano aqui no Google. Todos os anos, você pode comemorar a época de fim de ano com jogos e experiências educativas durante todo o mês de dezembro. Enquanto o Papai Noel tira uma folga merecida, os duendes tentam liberar o Siga o Papai Noel de código aberto, tanto na Web quanto para Android:

Na web, o Siga o Papai Noel é um site grande e interativo com muitas "cenas" exclusivas, escritas usando Polymer, compatível com a maioria dos navegadores mais recentes. Avaliar se o navegador de um usuário é "moderno" é determinado por meio da detecção de recursos: O Papai Noel exige Set e as a API Web Performance, entre outras outros.

Em 2016, atualizamos o mecanismo do Siga o Papai Noel para oferecer uma experiência off-line para a maioria cenas. Isso não inclui cenas com vídeos do YouTube ou sobre o local atual do Papai Noel, que só está disponível com uma conexão direta com o Polo Norte! 📶☃️

Siga o Papai Noel em um dispositivo Android
Siga o Papai Noel em um dispositivo Android

Desafios

O Papai Noel tem um design responsivo que funciona bem em celulares, tablets e computadores. O site encanta com recursos multimídia avançados, incluindo recursos visuais estilizados e áudio com tema de fim de ano. No entanto, uma versão normal do Siga o Papai Noel tem várias centenas de megabytes! Isso se deve a alguns motivos:

  • O Papai Noel tem suporte em mais de 35 idiomas e, por isso, muitos recursos devem ser duplicados.
  • Diferentes plataformas têm diferentes suportes de mídia (por exemplo, mp3 versus ogg).
  • Às vezes, os arquivos multimídia são fornecidos em tamanhos e resoluções diferentes.

Os duendes do Papai Noel também trabalham duro durante o mês de dezembro e costumam lançar atualizações novas e importantes. durante o mês. Isso significa que os recursos já armazenados em cache pelo navegador do usuário podem precisar ser atualizados em acessos repetidos.

Esses desafios:

  • Grandes recursos multimídia para diferentes "cenas"
  • Mudanças lançadas ao longo do mês

...resultam na inadequação de uma estratégia off-line simples.

Papai Noel, construído com a plataforma Polymer

Vale a pena voltar um pouco e falar sobre o design geral do Papai Noel antes de mergulhar em como nós atualizou-o para um PWA off-line.

O Papai Noel é um aplicativo de página única, originalmente escrito em Polymer 0.5, e agora atualizado para Polymer 1,7. O Papai Noel é composto de um conjunto compartilhado de códigos: o roteador, os recursos de navegação compartilhados etc. Ele também tem muitas "cenas" únicas.

Pré-carregador

Cada cena pode ser acessada por um URL diferente: /village.html, /codelab.html e /boatload.html, que é o próprio componente da Web. Quando um usuário abre uma cena, nós pré-carregamos todos os recursos HTML e recursos necessários (imagens, áudio, css, js) que estão em /scenes/[[sceneName]] no repositório do Siga o Papai Noel. Enquanto isso acontece, os usuários veem um pré-carregador amigável que mostra o progresso.

Essa abordagem significa que não precisamos carregar recursos desnecessários para cenas que o usuário não vê (o que são muitos dados). Isso também significa que precisamos manter um "manifesto de cache" interno de todos os recursos necessários cada cena. O manifesto de cache é um arquivo JSON que armazena um mapeamento do nome de arquivo para um hash MD5 do conteúdo dele.

Carregar o que você usa

Esse modelo economiza largura de banda, veiculando apenas recursos necessários para as cenas que um usuário visita, em vez do que pré-carregar todo o site de uma só vez. O Siga o Papai Noel aproveita a capacidade do Polymer de atualizar elementos personalizados no tempo de execução, tempo de carregamento atual. Considere o snippet a seguir:

<lazy-pages id="lazypages" selected-item="&#123;{selectedScene}}" ... >
    <dorf-scene id="village" route="village" icon="1f384" permanent
        mode$="[[mode]]"
        path$="scenes/dorf/dorf-scene_[[language]].html"
        class="santa-scene" allow-page-scrolling></dorf-scene>

    <boatload-scene route="boatload" icon="26f5"
        path$="scenes/boatload/boatload-scene_[[language]].html"
        loading-bg-color="#8fd7f7"
        loading-src="scenes/boatload/img/loading.svg"
        logo="scenes/boatload/img/logo.svg"
        class="santa-scene"></boatload-scene>

O Siga o Papai Noel realiza as seguintes etapas para carregar uma cena, por exemplo, boatload-scene:

  1. Todos os elementos da cena (incluindo <boatload-scene>) são inicialmente desconhecidos e são todos tratados como HTMLUnknownElement com alguns atributos adicionais.
  2. Quando a cena selecionada for alterada, o elemento <lazy-pages> será notificado.
  3. O elemento <lazy-pages> resolve o elemento da cena e o atributo path, carregando o HTML. importar scenes/boatload/boatload-scene_en.html. Contém o elemento Polymer e seus elementos dependentes.
  4. O pré-carregador amigável é exibido.
  5. Depois que a importação HTML é carregada e executada, <boatload-scene> é atualizado de forma transparente para um elemento polímero real, cheio de alegria natalina. 🎄🎉

Essa abordagem tem desafios. Por exemplo, não queremos incluir componentes da Web duplicados. Se duas cenas usarem um elemento comum, por exemplo, paper-button, ele será removido como parte do nosso build e incluí-lo no código compartilhado do Papai Noel.

Design off-line

O Siga o Papai Noel já está segmentado em cenas graças à biblioteca Polymer e à lazy-pages. mais cada tem o próprio diretório. Nós projetamos o service worker do Siga o Papai Noel, a parte central que permite o funcionamento off-line, que é executado em um navegador do usuário, para saber qual é o código compartilhado em vez da "cena" distinção.

Qual é a teoria por trás do service worker? Quando um usuário em um navegador compatível carrega seu site, o o HTML do front-end pode solicitar a instalação do service worker. Para o Siga o Papai Noel, o service worker mora em /sw.js. Isso dispara um evento install que armazenará em cache todo o código compartilhado do Papai Noel. buscada no momento da execução.

Diagrama de fluxo do software

O Service Worker, uma vez instalado, pode interceptar todas as solicitações HTTP. Para o recurso Siga o Papai Noel, o fluxo de decisão simplificado é semelhante a este:

  1. A solicitação já está armazenada em cache?
    • Ótimo! Retorne a resposta armazenada em cache.
  2. A solicitação corresponde a um diretório de cena, como "Scenes/boatload/boatload-scene_en.html"?
    • Execute uma solicitação de rede e armazene o resultado no cache antes de retorná-lo ao usuário.
  3. Caso contrário, faça uma solicitação de rede regular.

Nosso fluxo e o evento install permitem que o Siga o Papai Noel carregue mesmo que o usuário esteja off-line. No entanto, apenas as cenas que um usuário carregou anteriormente estarão disponíveis. Isso é perfeito para jogar novamente e superar sua maior pontuação.

Observadores atentos podem observar que nossa estratégia de armazenamento em cache não permite mudanças no conteúdo. Depois que um arquivo for armazenado em cache no navegador do usuário, ele nunca será alterado. Vamos falar sobre esse recurso mais adiante.

Vamos fazer isso ao vivo

Como mencionamos, os duendes do Papai Noel trabalham duro durante todo o mês de dezembro e, muitas vezes, precisam liberar novas atualizações ao longo do mês. Quando uma versão do Siga o Papai Noel é criada, ela recebe um rótulo exclusivo, por exemplo, v20161204112055, o carimbo de data/hora do lançamento (11:20:55 de 4 de dezembro de 2016).

Para esta versão identificada, geramos um hash MD5 de cada arquivo e o armazenamos em nosso manifesto". Em um disco de estado sólido moderno, isso adiciona apenas alguns segundos ao processo de build.

Cada versão é implantada em um caminho exclusivo no servidor de armazenamento em cache estático do Google. Ou seja, versões mais antigas nunca são removidas. Isso significa que, após um novo lançamento, todos os recursos terão um URL diferente, mesmo que não mudar e qualquer item armazenado em cache pelo navegador ou pelo service worker será inútil, a menos que façamos alguma um trabalho extra.

Também implantamos uma nova versão do que chamamos de "prod" recursos: HTML de índice e serviço do Papai Noel worker, que fica em https://santatracker.google.com/. Essa ação substitui a versão antiga.

Diagrama estático

Sempre que o Siga o Papai Noel é carregado, o navegador procura um service worker atualizado e o busca, se disponíveis. Em nosso caso, cada versão gera um código diferente em bytes. O navegador considera isso como um upgrade e executa um novo evento install.

Neste ponto, os navegadores do usuário examinarão o novo "manifesto de cache". Isso será comparado ao cache atual do usuário e, se os recursos tiverem um hash MD5 diferente, nós excluí-los do cache e pedir ao navegador para buscá-los novamente. No entanto, na maioria dos casos, o conteúdo armazenado em cache é basicamente o mesmo ou tem apenas pequenas diferenças.

Diagrama do cache

No Siga o Papai Noel, o upgrade do service worker faz com que o navegador do usuário seja recarregado imediatamente.

Experiência de navegação off-line

É claro que também tivemos que fazer algumas alterações na interface para oferecer uma experiência off-line e para tornar mais fácil de entender para os usuários que não esperam que um site funcione off-line.

Um banner pequeno informa quando você está navegando off-line. Todas as cenas que não são armazenadas em cache ficam "congeladas" e não clicável. Dessa forma, os usuários não podem acessar conteúdos que não estejam disponíveis.

Off-line

O Siga o Papai Noel faz solicitações regulares à API do Papai Noel. Se essas solicitações falharem ou atingirem o tempo limite, presumimos que o usuário está off-line. Usamos essa API em vez do navigator.onLine do navegador integrado propriedade: isso só informar se o usuário está on-line. Isso também é conhecido como Lie-Fi.

A conexão internacional

A maioria dos nossos usuários está em inglês (seguido por japonês, português, espanhol e francês), o Papai Noel é construído e lançado em mais de 35 idiomas diferentes.

Quando um usuário carrega o recurso "Siga o Papai Noel", usamos o idioma do navegador e outras dicas para escolher o idioma que será veiculado. A maioria dos usuários nunca substitui esse idioma. No entanto, se um usuário escolher um novo idioma por meio do nosso seletor, tratamos isso como se fosse um upgrade disponível—assim como no caso acima, quando uma nova versão do Siga o Papai Noel estiver disponível.

Idioma

Em outras palavras, a versão atual do Siga o Papai Noel para o propósito do service worker é uma tupla de (build,language).

Adicionar à tela inicial

Como o Papai Noel trabalha off-line e tem um service worker, os usuários qualificados são solicitados a instalar na tela inicial. Em 2016, cerca de 10% dos carregamentos qualificados eram provenientes do ícone da tela inicial.

Conclusão

Conseguimos converter rapidamente o Siga o Papai Noel em um PWA off-line, permitindo um ambiente experiência do cliente, graças ao nosso design de cenário existente, facilitado com o uso das ferramentas Polymer e componentes da Web. Ela também aproveita nosso sistema de build para realizar upgrades eficientes, invalidando apenas recursos alterados.

Embora o Papai Noel seja, em grande parte, uma solução personalizada, muitos de seus princípios podem ser encontrados na página da App Toolbox do projeto Sugerimos que você confira se estiver criando um novo PWA do zero ou se estiver procurando uma abordagem independente de framework, tente o Biblioteca Workbox.