Algumas pessoas, quando confrontadas com um determinado problema, pensam: “Vou usar User Agent (UA)/detecção de dispositivos!” Agora, elas têm dois problemas…
Mas, apesar de todas as armadilhas, UA (User-Agent) ou detecção de dispositivos é um fato da vida, um negócio em crescimento, e um requisito de negócios favorável para muitos. O problema é que a detecção de dispositivo muitas vezes não classifica os clientes capazes de realizar essa interpretação (por exemplo, o IE11 foi forçado a mudar sua política de UA); leva a pesadelos de compatibilidade; não pode permanecer continuamente mudando as preferências do usuário e seu tempo de execução. Dito isso, quando utilizado corretamente, UA também pode ser usada para o bem.
Fabricantes de navegadores adorariam deixar de lado UA inteiramente, mas isso iria fazer com que muitas coisas parassem de funcionar. No entanto, ao mesmo tempo em que está na moda demonizar a detecção de dispositivo, a raiz do problema não é a intenção por trás disso, mas é a forma como é distribuída atualmente. Em vez de “detectar” (ou seja, supor) os recursos do cliente por meio de uma sequência de versões similares, é preciso mudar o modelo para permitir que o agente do usuário verifique as capacidades necessárias.
Consideramos então que isso é não uma ideia nova, mas as tentativas anteriores parecem apresentar algumas questões a serem resolvidas: buscam padronizar a lista de capacidades; exigem acordo entre várias partes (fornecedores de UA, fabricantes de dispositivos etc.); eles são mais focados em engenharia? Em vez disso, o que precisamos é de uma plataforma primitiva que seja:
- Flexível: fabricantes de navegadores não podem prever todos os casos de uso, nem querem ou precisam estar nesse negócio. Devem apenas fornecer orientação de implementação e documentar as melhores práticas.
- Deploy fácil: os desenvolvedores devem estar no controle sobre quais recursos são relatados. Sem bloqueio nas políticas do User Agent ou recursos de terceiros.
- Fácil de operar: compatível e implementável com a infraestrutura existente. Não há necessidade de bases de dados de terceiros, contratos de serviços ou outras dependências no caminho.
Aqui está a boa notícia: já existe esse mecanismo, e ele se chama Service Worker. Vamos dar uma olhada nele mais de perto…
O service worker é um serviço web orientado a eventos, que responde a eventos disparados a partir de documentos e outras fontes … O service worker é um ponto de entrada de dados genéricos para processamento em segundo plano na plataforma web e que é extensível por outras especificações – ver explainer, usando o service worker e o livro cookbook sobre o assunto.
Uma maneira simples de entender o service worker é pensar nele como um proxy programável que é executado em seu navegador e é capaz de ver, modificar e responder a todas as solicitações iniciadas pela página em que está instalado. Como resultado, o desenvolvedor pode usá-lo para anotar pedidos de saída (através dos cabeçalhos da requisição HTTP ou da regravação de um URL), com capacidade de anúncios relevantes:
- O desenvolvedor define quais recursos são relatados e onde devem ser solicitados.
- Checagem de capacidade é executada no client – sem adivinhações no servidor.
- Os valores apresentados são dinâmicos e capazes de refletir as mudanças na preferência do usuário e no ambiente de tempo de execução.
Essa não é uma proposta ou uma lista de desejos – essas informações são atuais e esses recursos estão disponíveis hoje, e são resultado direto da permissão das poderosas primitivas de baixo nível do navegador utilizado. Como tal, agora é só uma questão de estabelecer as melhores práticas: o que nós relatamos, em qual formato, e como nós otimizamos interoperabilidade? Vamos considerar um exemplo do mundo real…
A experiência da startup de vídeo otimizando
Nosso objetivo é entregar a melhor – mais rápida e visualmente agradável – experiência de execução de vídeo para nossos usuários. Iniciar com a menor taxa de bits é abaixo do ideal: é rápido, mas possui uma baixa qualidade visual consistente para todos os usuários, mesmo para aqueles que possuem uma conexão rápida. Em vez disso, queremos escolher um bitrate de partida que pode entregar a melhor experiência visual, desde o início, minimizando atrasos de reprodução e rebuffers. Não precisamos ser perfeitos, mas devemos contabilizar o tempo de rede atual no cliente. Depois que o vídeo começa a tocar, o streaming de bitrate adaptável vai assumir e ajustar a qualidade de fluxo para cima ou para baixo, conforme necessário.
A combinação do service worker com a Network Information API faz este papel de implementação:
// register the service worker navigator.serviceWorker.register('/worker.js').then( function(reg) { console.log('Installed successfully', reg) }, function(err) { console.log('Worker installation failed', err) } ); // ... worker.js self.addEventListener('fetch', function(event) { var requestURL = new URL(event.request); // Intercept same origin /video/* requests if (requestURL.origin == location.origin) { if (/^\/video\//.test(requestURL.pathname)) { // append the MD header, set value to NetInfo's downlinkMax: // http://w3c.github.io/netinfo/#downlinkmax-attribute event.respondWith( fetch(event.request.url, { headers: { 'MD': navigator.connection.downlinkMax } }) ); return; } } });
- O site instala um script service worker que tem como escopo capturar pedidos com a tag /vídeo/*.
- Quando uma solicitação de vídeo é detectada, o worker acrescenta o cabeçalho MD e define seu valor para a atual velocidade máxima do link de download. Nota: o plano atual é permitir o downlinkMax no Chrome 41.
- O servidor recebe a solicitação do vídeo, consulta o valor MD para determinar o bitrate inicial, e responde com o trecho de vídeo adequado (uma vez que o vídeo é enviado em partes para melhorar a velocidade).
Nós temos total controle sobre o fluxo de solicitação e somos capazes de adicionar dados para o pedido antes de enviá-lo para o servidor. O melhor de tudo é que essa lógica é transparente para o aplicativo, e você está livre para personalizá-la ainda mais, caso tenha necessidade. Por exemplo, caso deseje adicionar uma substituição explícita de usuário para definir um bitrate de partida, solicite que o usuário envie o valor para o worker caso ache esse valor o ideal.
Cansado de escrever regras de srcset para cada imagem em seu código? O service worker pode ajudar a entregar tags DPR para <img>: use o script de negociação de conteúdo, ou reescreva a imagem da URL. Note que cada dispositivo DPR possui um valor dinâmico: dar zoom em uma imagem em um navegador web afeta o valor do DPR! Os métodos de detecção de dispositivo existentes não podem ser responsáveis por isso.
Melhores práticas de implementação
Os service workers (para desenvolvedores web) permitem definir, personalizar e implementar novos parâmetros de capacidade à vontade: podemos reescrever pedidos, implementar tipos de conteúdo ou regras específicas de origem, contas para as preferências do usuário. As novas questões em aberto são: quais as capacidades que nossos servidores precisam suportar e qual é a melhor maneira de entregá-las?
Vai ser tentador relatar cada propriedade individual e de forma personalizada para cada cliente. Por favor, pense duas vezes antes de fazer isso, pois isso pode adicionar uma sobrecarga significativa ao servidor para cada pedido – seja criterioso. Da mesma forma, faz sentido otimizar a interoperabilidade: usar nomes de parâmetros e formatos que funcionem bem com a infraestrutura e serviços atuais – caches e CDN, serviços de otimização, e assim por diante, podem ser uma boa ideia. Por exemplo, os pedidos MD e DPR de cabeçalhos usados nos exemplos acima vêm de dicas de clientes, cujos objetivos são:
- Documentar as melhores práticas para a comunicação da capacidade do cliente através de campos de cabeçalho de solicitação HTTP.
- Atuar como um registro para campos de cabeçalho comuns de forma a ajudar a interoperabilidade entre diferentes serviços.
- por exemplo, você pode usar DPR e RW para otimizar as imagens que utilizam o serviço resrc.it.
Agora é a hora de experimentar. Haverá percalços e pobres implementações iniciais, mas bons padrões e melhores práticas surgirão. Mais importante ainda, o ciclo de aprendizagem para testar e melhorar essa infraestrutura está agora firmemente nas mãos dos desenvolvedores web: implantar o service worker, experimentar, aprender e interagir.
***
Ilya Grigorik faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: https://www.igvita.com/2014/12/15/capability-reporting-with-service-worker/