Oferecer aplicativos rápidos e leves com o Save-Data

O cabeçalho de solicitação de dica do cliente Save-Data, disponível nos navegadores Chrome, Opera e Yandex, permite que os desenvolvedores ofereçam apps mais leves e rápidos para usuários que ativam o modo de economia de dados no navegador.

A necessidade de páginas leves

Estatísticas do Weblight

Todos concordam que páginas da Web mais rápidas e leves proporcionam uma experiência do usuário mais satisfatória, permitem melhor compreensão e retenção de conteúdo e geram mais conversões e receita. A pesquisa do Google mostrou que "páginas otimizadas são carregadas quatro vezes mais rápido do que a página original e usam 80% menos bytes. Como essas páginas carregam muito mais rápido, também percebemos um aumento de 50% no tráfego delas."

Embora o número de conexões 2G esteja finalmente em declínio, o 2G ainda era a tecnologia de rede dominante em 2015. A penetração e a disponibilidade das redes 3G e 4G estão crescendo rapidamente, mas os custos de propriedade e as restrições de rede associados ainda são um fator significativo para centenas de milhões de usuários.

Esses são bons argumentos para a otimização da página.

Existem métodos alternativos para melhorar a velocidade do site sem o envolvimento direto do desenvolvedor, como navegadores proxy e serviços de transcodificação. Embora esses serviços sejam bastante usados, eles apresentam desvantagens substanciais: compactação de imagem e texto simples (e às vezes inaceitável), incapacidade de processar páginas seguras (HTTPS), otimização apenas de páginas visitadas por meio de um resultado de pesquisa e muito mais. A própria popularidade desses serviços é um indicador de que os desenvolvedores da Web não estão atendendo adequadamente à alta demanda dos usuários por apps e páginas rápidos e leves. Mas atingir essa meta é um caminho complexo e às vezes difícil.

O cabeçalho da solicitação Save-Data

Uma técnica bastante simples é deixar o navegador ajudar, usando o cabeçalho de solicitação Save-Data. Ao identificar esse cabeçalho, uma página da Web pode personalizar e oferecer uma experiência otimizada ao usuário para usuários com limitações de custo e desempenho.

Os navegadores compatíveis (abaixo) permitem que o usuário ative um *modo de economia de dados, que concede ao navegador permissão para aplicar um conjunto de otimizações e reduzir a quantidade de dados necessários para renderizar a página. Quando esse recurso é exposto ou anunciado, o navegador pode solicitar imagens de resolução mais baixa, adiar o carregamento de alguns recursos ou rotear solicitações por um serviço que aplica outras otimizações específicas do conteúdo, como compactação de recursos de imagem e texto.

Suporte ao navegador

Detectando a configuração Save-Data

Para determinar quando oferecer a experiência "leve" aos usuários, seu aplicativo pode verificar o cabeçalho de solicitação de dica do cliente Save-Data. Esse cabeçalho de solicitação indica a preferência do cliente por uso reduzido de dados devido a altos custos de transferência, velocidades de conexão lentas ou outros motivos.

Quando o usuário ativa o modo de economia de dados no navegador, o navegador anexa o cabeçalho da solicitação Save-Data a todas as solicitações de saída (HTTP e HTTPS). No momento em que este artigo foi escrito, o navegador anuncia somente um token *on- no cabeçalho (Save-Data: on), mas isso pode ser estendido no futuro para indicar outras preferências do usuário.

Além disso, é possível detectar se Save-Data está ativado no JavaScript:

if ('connection' in navigator) {
  if (navigator.connection.saveData === true) {
    // Implement data saving operations here.
  }
}

A verificação da presença do objeto connection no objeto navigator é essencial, porque representa a API Network Information, que é implementada apenas nos navegadores de Internet Chrome, Chrome para Android e Samsung. Depois, você só precisa verificar se navigator.connection.saveData é igual a true, e é possível implementar qualquer operação de economia de dados nessa condição.

O
cabeçalho "Save-Data" mostrado nas Ferramentas para desenvolvedores do Chrome com a
extensão "Economia de dados".
Ativar a extensão Economia de dados no Chrome para computador
.

Se o aplicativo usar um service worker, ele poderá inspecionar os cabeçalhos da solicitação e aplicar a lógica relevante para otimizar a experiência. Como alternativa, o servidor pode procurar as preferências anunciadas no cabeçalho da solicitação Save-Data e retornar uma resposta alternativa, como uma marcação diferente, imagens e vídeos menores e assim por diante.

Dicas de implementação e práticas recomendadas

  1. Ao usar Save-Data, forneça alguns dispositivos de IU com suporte e permita que os usuários alternem facilmente entre as experiências. Por exemplo:
    • Informe aos usuários que o Save-Data é compatível e incentive o uso do app.
    • Permita que os usuários identifiquem e escolham o modo com solicitações adequadas e botões de ativação/desativação ou caixas de seleção intuitivos.
    • Quando o modo economia de dados for selecionado, anuncie e forneça uma maneira fácil e óbvia de desativá-lo e voltar à experiência completa, se desejado.
  2. Lembre-se de que aplicativos leves não são aplicativos menores. Eles não omitem funcionalidades ou dados importantes, apenas reconhecem melhor os custos envolvidos e a experiência do usuário. Exemplo:
    • Um aplicativo de galeria de fotos pode oferecer visualizações de resolução mais baixa ou usar um mecanismo de carrossel com menos uso de código.
    • Um app de pesquisa pode retornar menos resultados por vez, limitar o número de resultados com uso intenso de mídia ou reduzir o número de dependências necessárias para renderizar a página.
    • Um site voltado a notícias pode mostrar menos matérias, omitir categorias menos acessadas ou fornecer visualizações de mídia menores.
  3. Forneça a lógica do servidor para verificar o cabeçalho da solicitação Save-Data e considere fornecer uma resposta de página alternativa e mais leve quando ela estiver ativada. Por exemplo, reduza o número de recursos e dependências necessários, aplique uma compactação de recursos mais agressiva etc.
    • Se você estiver exibindo uma resposta alternativa com base no cabeçalho Save-Data, lembre-se de adicioná-la à lista de variantes (Vary: Save-Data) para informar aos caches upstream que eles precisam armazenar em cache e veicular essa versão somente se o cabeçalho de solicitação Save-Data estiver presente. Para mais detalhes, consulte as práticas recomendadas de interação com caches.
  4. Se você usar um service worker, seu aplicativo poderá detectar quando a opção de salvamento de dados estiver ativada verificando a presença do cabeçalho de solicitação Save-Data ou verificando o valor da propriedade navigator.connection.saveData. Se ativado, considere se você pode reescrever a solicitação para buscar menos bytes ou usar uma resposta já buscada.
  5. Considere aumentar Save-Data com outros sinais, como informações sobre o tipo de conexão e a tecnologia do usuário (consulte API NetInfo). Por exemplo, talvez você queira disponibilizar a experiência leve para qualquer usuário em uma conexão 2G, mesmo que Save-Data não esteja ativado. Por outro lado, só porque o usuário está em uma conexão 4G "rápida" não significa que ele não está interessado em salvar dados, por exemplo, quando está em roaming. Além disso, é possível aumentar a presença de Save-Data com a dica do cliente Device-Memory para se adaptar ainda mais a usuários em dispositivos com memória limitada. A memória do dispositivo do usuário também é divulgada na dica de cliente navigator.deviceMemory.

Recipes

O que você pode conseguir com Save-Data é limitado apenas ao que você pode criar. Para dar uma ideia do que é possível, vamos examinar alguns casos de uso. Durante a leitura, você pode criar outros casos de uso, então fique à vontade para testar e ver o que é possível.

Verificando Save-Data no código do lado do servidor

Embora o estado Save-Data seja algo que pode ser detectado em JavaScript usando a propriedade navigator.connection.saveData, detectar no lado do servidor às vezes é preferível. O JavaScript pode não ser executado em alguns casos. Além disso, a detecção do lado do servidor é a única maneira de modificar a marcação antes de ser enviada ao cliente, que está envolvida em alguns dos casos de uso mais benéficos de Save-Data.

A sintaxe específica para detectar o cabeçalho Save-Data no código do lado do servidor depende da linguagem usada, mas a ideia básica precisa ser a mesma para qualquer back-end de aplicativo. No PHP, por exemplo, os cabeçalhos da solicitação são armazenados na matriz superglobal $_SERVER em índices que começam com HTTP_. Isso significa que você pode detectar o cabeçalho Save-Data verificando a existência e o valor da variável $_SERVER["HTTP_SAVE_DATA"] da seguinte maneira:

// false by default.
$saveData = false;

// Check if the `Save-Data` header exists and is set to a value of "on".
if (isset($_SERVER["HTTP_SAVE_DATA"]) && strtolower($_SERVER["HTTP_SAVE_DATA"]) === "on") {
  // `Save-Data` detected!
  $saveData = true;
}

Se você fizer essa verificação antes de qualquer marcação ser enviada ao cliente, a variável $saveData conterá o estado Save-Data e estará disponível para uso na página. Com esse mecanismo ilustrado, vamos conferir alguns exemplos de como podemos usá-lo para limitar a quantidade de dados enviados ao usuário.

Exibir imagens de baixa resolução para telas de alta resolução

Um caso de uso comum para imagens na Web envolve a exibição de imagens em conjuntos de duas: uma imagem para telas "padrão" (1x) e outra imagem que é duas vezes maior (2x) para telas de alta resolução (por exemplo, Tela Retina. Essa classe de telas de alta resolução não é necessariamente limitada a dispositivos de última geração e está se tornando cada vez mais comum. Nos casos em que uma experiência de aplicativo mais leve é preferida, pode ser prudente enviar imagens de resolução mais baixa (1x) para essas telas, em vez de variantes maiores (2x). Para fazer isso quando o cabeçalho Save-Data estiver presente, basta modificar a marcação que enviamos ao cliente:

if ($saveData === true) {
  // Send a low-resolution version of the image for clients specifying `Save-Data`.
  ?><img src="butterfly-1x.jpg" alt="A butterfly perched on a flower."><?php
}
else {
  // Send the usual assets for everyone else.
  ?><img src="butterfly-1x.jpg" srcset="butterfly-2x.jpg 2x, butterfly-1x.jpg 1x" alt="A butterfly perched on a flower."><?php
}

Esse caso de uso é um exemplo perfeito de como é necessário pouco esforço para acomodar alguém que está pedindo especificamente que você envie menos dados. Se você não gosta de modificar a marcação no back-end, também pode alcançar o mesmo resultado usando um módulo de reescrita de URL, como o mod_rewrite do Apache (link em inglês). Existem exemplos de como fazer isso com relação relativamente pequena de configuração.

Também é possível ampliar esse conceito para as propriedades background-image do CSS adicionando uma classe ao elemento <html>:

<html class="<?php if ($saveData === true): ?>save-data<?php endif; ?>">

A partir daqui, é possível segmentar a classe save-data no elemento <html> do seu CSS para alterar a forma como as imagens são exibidas. É possível enviar imagens de plano de fundo de baixa resolução para telas de alta resolução, conforme mostrado no exemplo HTML acima, ou omitir completamente determinados recursos.

Omita imagens não essenciais

Alguns conteúdos de imagem na web simplesmente não são essenciais. Embora essas imagens possam ser benéficas para o conteúdo, elas podem não ser desejáveis para aqueles que tentam eliminar tudo o que conseguir de planos de dados limitados. No que talvez seja o caso de uso mais simples de Save-Data, podemos usar o código de detecção PHP mostrado anteriormente e omitir completamente a marcação de imagem não essencial:

<p>This paragraph is essential content. The image below may be humorous, but it's not critical to the content.</p>
<?php
if ($saveData === false) {
  // Only send this image if `Save-Data` hasn't been detected.
  ?><img src="meme.jpg" alt="One does not simply consume data."><?php
}

Essa técnica certamente pode ter um efeito pronunciado, como você pode conferir na figura abaixo:

Comparação entre imagens não críticas
que são carregadas quando os dados salvos estão ausentes e essas mesmas imagens sendo omitidas
quando o recurso &quot;Salvar dados&quot; está presente.
Comparação de imagens não críticas que são carregadas quando não há dados salvos em relação às mesmas imagens que são omitidas quando o recurso está presente.

Obviamente, omitir imagens não é a única possibilidade. Também é possível agir em Save-Data para abandonar o envio de outros recursos não essenciais, como alguns tipos de fontes.

Omitir fontes da Web não essenciais

Embora as fontes da Web normalmente não componham tanto o payload total de uma página como as imagens geralmente, elas ainda são bastante usadas. Eles também não consomem uma quantidade insignificante de dados. Além disso, a maneira como os navegadores buscam e renderizam fontes é mais complicada do que você imagina, com conceitos como FOIT, FOUT e heurísticas do navegador tornando a renderização uma operação diferenciada.

Pode parecer razoável, nesse caso, deixar de fora fontes da Web não essenciais para usuários que querem experiências do usuário mais enxutas. Com Save-Data, isso é bastante fácil.

Por exemplo, digamos que você incluiu Fira Sans do Google Fonts no seu site. A Fira Sans é uma excelente fonte de texto corporal, mas talvez ela não seja tão crucial para usuários que tentam salvar dados. Ao adicionar uma classe de save-data ao elemento <html> quando o cabeçalho Save-Data está presente, podemos escrever estilos que invocam a família tipográfica não essencial no início, mas o desativa quando o cabeçalho Save-Data está presente:

/* Opt into web fonts by default. */
p,
li {
  font-family: 'Fira Sans', 'Arial', sans-serif;
}

/* Opt out of web fonts if the `save-Data` class is present. */
.save-data p,
.save-data li {
  font-family: 'Arial', sans-serif;
}

Usando essa abordagem, você pode manter o snippet <link> do Google Fonts porque o navegador carrega recursos CSS de maneira especulativa (incluindo fontes da Web) aplicando estilos ao DOM e depois verificando se algum elemento HTML invoca algum dos recursos na folha de estilo. Se alguém usar Save-Data ativado, a Fira Sans nunca será carregada porque o DOM estilizado nunca o invocará. Arial vai entrar. Não é tão bom quanto o da Fira Sans, mas pode ser preferível aos usuários que tentam ampliar seus planos de dados.

Resumo

O cabeçalho Save-Data não tem muitas nuances. Ele está ativado ou desativado, e o aplicativo arca com o ônus de fornecer experiências adequadas com base na configuração dele, independentemente do motivo.

Por exemplo, alguns usuários podem não permitir o modo economia de dados se suspeitarem que haverá uma perda de conteúdo ou função do app, mesmo em uma situação de conectividade instável. Por outro lado, alguns usuários podem ativá-lo, obviamente, para manter as páginas o mais pequenas e simples possível, mesmo em uma boa situação de conectividade. É melhor que o app presuma que o usuário quer a experiência completa e ilimitada até que haja uma indicação clara do contrário por uma ação do usuário explícita.

Como proprietários de sites e desenvolvedores da Web, assumimos a responsabilidade de gerenciar nosso conteúdo para melhorar a experiência do usuário para usuários com restrições de dados e custos.

Para mais detalhes sobre Save-Data e excelentes exemplos práticos, consulte Ajude seus usuários Save Data.