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 aplicativos mais leves e rápidos aos 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. Uma pesquisa do Google mostrou que "... páginas otimizadas carregam 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 registramos um aumento de 50% no tráfego delas."

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

Esses são bons argumentos para a otimização das páginas.

Há 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 conhecidos, eles têm desvantagens substanciais: compactação simples (e às vezes inaceitável) de imagem e texto, incapacidade de processar páginas seguras (HTTPS), otimização apenas de páginas visitadas por meio de um resultado da pesquisa e muito mais. A própria popularidade desses serviços é um indicador de que os desenvolvedores da Web não estão abordando adequadamente a alta demanda de usuários por aplicativos e páginas rápidos e leves. Mas alcançar essa meta é um caminho complexo e, às vezes, difícil.

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

Uma técnica bastante direta é 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 do usuário otimizada a usuários com restrições de custo e desempenho.

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

Suporte ao navegador

Detectar a configuração Save-Data

Para determinar quando proporcionar a experiência "leve" aos usuários, seu aplicativo pode verificar o cabeçalho de solicitação de dica de cliente Save-Data. Esse cabeçalho da solicitação indica a preferência do cliente pela redução do uso 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, o navegador anexa o cabeçalho da solicitação Save-Data a todas as solicitações enviadas (HTTP e HTTPS). No momento, o navegador anuncia apenas 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 o 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, já que representa a API Network Information, que é implementada apenas nos navegadores de Internet Chrome, Chrome para Android e Samsung. A partir daí, você só precisa verificar se navigator.connection.saveData é igual a true e pode implementar qualquer operação de salvamento de dados nessa condição.

O
cabeçalho "Save-Data" mostrado nas Ferramentas para desenvolvedores do Chrome junto com a
extensão Economia de dados.
Ativando 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 (marcação diferente, imagens e vídeos menores etc.).

Dicas de implementação e práticas recomendadas

  1. Ao usar Save-Data, forneça alguns dispositivos de interface com suporte a ele e permita que os usuários alternem entre as experiências com facilidade. Por exemplo:
    • Notifique os usuários de que o Save-Data é compatível e incentive-os a usar o recurso.
    • Permita que os usuários identifiquem e escolham o modo com as solicitações apropriadas e botões ou caixas de seleção intuitivos de ativar/desativar.
    • Quando o modo economia de dados for selecionado, anuncie e ofereça uma maneira fácil e óbvia de desativá-lo e voltar à experiência completa, se você quiser.
  2. Lembre-se de que aplicativos leves não são aplicativos menores. Elas não omitem funcionalidades ou dados importantes, apenas estão mais conscientes dos custos envolvidos e da 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 que não exige muito código.
    • Um app de pesquisa pode retornar menos resultados por vez, limitar o número de resultados de mídia pesada ou reduzir o número de dependências necessárias para renderizar a página.
    • Um site de notícias pode mostrar menos matérias, omitir categorias menos conhecidas ou fornecer visualizações de mídia menores.
  3. Forneça uma lógica de 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 Vary (Vary: Save-Data) para informar aos caches upstream que eles precisam armazenar em cache e disponibilizar essa versão somente se o cabeçalho da 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 está ativada, verificando a presença do cabeçalho da solicitação Save-Data ou verificando o valor da propriedade navigator.connection.saveData. Se ativado, avalie se é possível reescrever a solicitação para buscar menos bytes ou usar uma resposta já buscada.
  5. Considere aumentar o Save-Data com outros indicadores, como informações sobre o tipo e a tecnologia de conexão do usuário (consulte API NetInfo). Por exemplo, é possível oferecer a experiência leve a qualquer usuário em uma conexão 2G, mesmo que Save-Data não esteja ativado. Por outro lado, o fato de o usuário estar em uma conexão 4G rápida não significa que ele não tem interesse em salvar dados, por exemplo, em roaming. Além disso, é possível aumentar a presença de Save-Data com a dica de cliente Device-Memory para se adaptar ainda mais aos usuários em dispositivos com memória limitada. A memória do dispositivo do usuário também é divulgada na dica do cliente navigator.deviceMemory.

Recipes

O que você pode alcançar com o Save-Data é limitado apenas ao que você pode conseguir. Para dar uma ideia do que é possível, vamos ver alguns casos de uso. Ao ler isto, você pode sugerir 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 você pode detectar no JavaScript usando a propriedade navigator.connection.saveData, detectá-lo no lado do servidor às vezes é preferível. A execução do JavaScript pode falhar em alguns casos. Além disso, a detecção no lado do servidor é a única maneira de modificar a marcação antes de ela ser enviada ao cliente, o que está envolvido em alguns dos casos de uso mais benéficos do 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 em qualquer lugar para uso na página. Com esse mecanismo ilustrado, vamos conferir alguns exemplos de como usá-lo para limitar a quantidade de dados que enviamos ao usuário.

Veicular 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 dois: 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 quanto esforço é necessário 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 conseguir o mesmo resultado usando um módulo de regravação de URL, como o mod_rewrite da Apache. Há exemplos de como fazer isso com relativamente pouca configuração.

Você também pode estender esse conceito para propriedades CSS background-image simplesmente 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> no seu CSS para mudar a forma como as imagens são entregues. É possível enviar imagens de plano de fundo de baixa resolução para telas de alta resolução, como mostrado no exemplo de HTML acima, ou omitir determinados recursos completamente.

Omita imagens não essenciais

Alguns conteúdos de imagem na Web simplesmente não são essenciais. Embora essas imagens possam ser belas ao lado do conteúdo, elas podem não ser desejáveis para pessoas que tentam espremer tudo o que podem dos 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 anterior 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 mostrado na figura abaixo:

Uma comparação entre imagens não críticas que estão sendo carregadas quando Save-Data está ausente, com a mesma imagem sendo omitida quando Save-Data está presente.
Uma comparação entre imagens não críticas que estão sendo carregadas quando a função Save-Data está ausente, com as mesmas imagens sendo omitidas quando Save-Data está presente.

Obviamente, omitir imagens não é a única possibilidade. Também é possível agir no Save-Data para abandonar o envio de outros recursos não críticos, como determinadas famílias tipográficas.

Omitir fontes da Web não essenciais

Embora as fontes da Web geralmente não representem quase a mesma quantidade de payload de uma determinada página quanto as imagens costumam fazer, elas ainda são muito 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ística do navegador, tornando a renderização uma operação com nuances.

Por isso, talvez você não queira usar fontes da Web não essenciais para os usuários que querem experiências mais simples. Save-Data torna isso uma tarefa razoavelmente fácil.

Por exemplo, digamos que você inclua o Fira Sans do Google Fonts no seu site. Fira Sans é uma excelente fonte de texto do corpo, mas talvez não seja tão importante para usuários que tentam salvar dados. Ao adicionar uma classe 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 a desativam 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;
}

Com essa abordagem, você pode manter o snippet <link> do Google Fonts, já que o navegador carrega recursos CSS (incluindo fontes da Web) de maneira especulativa aplicando estilos ao DOM e verificando se algum elemento HTML invoca algum dos recursos na folha de estilos. Se alguém acontecer com Save-Data ativado, a Fira Sans nunca será carregada porque o DOM estilizado nunca a invoca. A Arial será aplicada. Não é tão bom quanto 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 assume o ônus de fornecer experiências adequadas com base na configuração, independente do motivo.

Por exemplo, alguns usuários podem não permitir o modo de economia de dados se suspeitarem que haverá uma perda de conteúdo ou função do app, mesmo em uma situação de conectividade ruim. Por outro lado, alguns usuários podem ativar esse recurso 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 você tenha uma indicação clara do contrário por uma ação explícita do usuário.

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

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