Desenvolver sites rápidos em todos os lugares pode ser uma perspectiva difícil. A grande quantidade de recursos dos dispositivos e a qualidade das redes a que eles se conectam podem fazer com que pareça uma tarefa impossível. Embora possamos aproveitar os recursos do navegador para melhorar o desempenho do carregamento, como saber do que o dispositivo do usuário é capaz ou a qualidade da conexão de rede dele? A solução são dicas do cliente.
As dicas de cliente são um conjunto de cabeçalhos de solicitação HTTP ativados que nos dão insights sobre esses aspectos do dispositivo do usuário e da rede a que ele está conectado. Ao acessar essas informações no lado do servidor, podemos mudar como entregamos conteúdo com base nas condições do dispositivo e/ou da rede. Isso pode nos ajudar a criar experiências do usuário mais inclusivas.
It’s All About Content Negotiation
As dicas de cliente são outro método de negociação de conteúdo, ou seja, mudar as respostas de conteúdo com base nos cabeçalhos de solicitação do navegador.
Um exemplo de negociação de conteúdo envolve o cabeçalho da solicitação
Accept. Ele descreve quais tipos de conteúdo o navegador entende, que
o servidor pode usar para negociar a resposta. Para solicitações de imagem, o conteúdo
do cabeçalho Accept do Chrome é:
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Embora todos os navegadores sejam compatíveis com formatos de imagem como JPEG, PNG e GIF, o Accept informa, nesse caso, que o navegador também é compatível com WebP e APNG. Com essas informações, podemos negociar os melhores tipos de imagem para cada navegador:
<?php
// Check Accept for an "image/webp" substring.
$webp = stristr($_SERVER["HTTP_ACCEPT"], "image/webp") !== false ? true : false;
// Set the image URL based on the browser's WebP support status.
$imageFile = $webp ? "whats-up.webp" : "whats-up.jpg";
?>
<img src="<?php echo($imageFile); ?>" alt="I'm an image!">
Assim como Accept, as dicas de cliente são outra maneira de negociar conteúdo, mas no contexto de recursos do dispositivo e condições de rede. Com as dicas de cliente, podemos tomar decisões de performance do lado do servidor com base na experiência individual de um usuário, como decidir se recursos não críticos devem ser veiculados para usuários com condições de rede ruins. Neste guia, vamos descrever todas as dicas disponíveis e algumas maneiras de usá-las para tornar a entrega de conteúdo mais conveniente para os usuários.
Ativação
Ao contrário do cabeçalho Accept, as dicas de cliente não aparecem magicamente, com exceção de Save-Data, que vamos discutir mais adiante. Para manter os cabeçalhos de solicitação no mínimo, você precisa ativar as dicas de cliente que quer receber enviando um cabeçalho Accept-CH quando um usuário solicita um recurso:
Accept-CH: Viewport-Width, Downlink
O valor de Accept-CH é uma lista separada por vírgulas de dicas solicitadas que o site
usará para determinar os resultados da solicitação de recurso subsequente. Quando o
cliente lê esse cabeçalho, ele recebe a mensagem "este site quer as dicas de cliente Viewport-Width
e Downlink". Não se preocupe com as dicas específicas.
Vamos falar sobre isso daqui a pouco.
É possível definir esses cabeçalhos de ativação em qualquer linguagem de back-end. Por exemplo, é possível usar a função
header do PHP.
Você pode até mesmo definir esses cabeçalhos de ativação com o atributo http-equiv em uma tag <meta>:
<meta http-equiv="Accept-CH" content="Viewport-Width, Downlink" />
Todas as dicas de cliente!
As dicas de cliente descrevem uma de duas coisas: o dispositivo que seus usuários usam e a rede que eles estão usando para acessar seu site. Vamos abordar brevemente todas as dicas disponíveis.
Dicas do dispositivo
Algumas dicas de cliente descrevem características do dispositivo do usuário, geralmente da tela. Alguns deles podem ajudar você a escolher o recurso de mídia ideal para a tela de um determinado usuário, mas nem todos são necessariamente focados em mídia.
Antes de começar a lista, é útil aprender alguns termos importantes usados para descrever telas e resolução de mídia:
Tamanho intrínseco:as dimensões reais de um recurso de mídia. Por exemplo, se você abrir uma imagem no Photoshop, as dimensões mostradas na caixa de diálogo de tamanho da imagem descrevem o tamanho intrínseco dela.
Tamanho intrínseco corrigido pela densidade:as dimensões de um recurso de mídia depois de corrigido para densidade de pixels. É o tamanho intrínseco da imagem dividido por uma proporção de pixels do dispositivo. Por exemplo, considere esta marcação:
<img
src="whats-up-1x.png"
srcset="whats-up-2x.png 2x, whats-up-1x.png 1x"
alt="I'm that image you wanted."
/>
Digamos que o tamanho intrínseco da imagem 1x neste caso seja 320 x 240, e o tamanho intrínseco da imagem 2x seja 640 x 480. Se essa marcação for analisada por um cliente instalado em um dispositivo com uma proporção de pixels do dispositivo de tela de 2 (por exemplo, uma tela Retina), a imagem 2x será solicitada. O tamanho intrínseco corrigido pela densidade da imagem 2x é 320 x 240, já que 640 x 480 dividido por 2 é 320 x 240.
Tamanho extrínseco:o tamanho de um recurso de mídia depois que o CSS e outros fatores de layout (como atributos width e height) são aplicados a ele. Suponha que você tenha um elemento <img> que carrega uma imagem com um tamanho intrínseco corrigido por densidade de 320 x 240, mas também tenha propriedades CSS width e height com valores de 256px e 192px aplicados a ele, respectivamente. Neste exemplo, o tamanho extrínseco do elemento <img> se torna 256 x 192.
width: 256px; e height: 192px; transforma uma imagem de tamanho intrínseco de 320 x 240 em uma de tamanho extrínseco de 256 x 192.Agora que já entendemos alguns termos, vamos conferir a lista de dicas de cliente específicas do dispositivo disponíveis para você.
Viewport-Width
Viewport-Width é a largura da janela de visualização do usuário em pixels CSS:
Viewport-Width: 320
Essa dica pode ser usada com outras dicas específicas da tela para oferecer diferentes tratamentos (ou seja, cortes) de uma imagem que são ideais para tamanhos de tela específicos (ou seja, direção de arte), ou para omitir recursos desnecessários para a largura da tela atual.
DPR
DPR, abreviação de proporção de pixels do dispositivo, informa a proporção de pixels físicos para pixels CSS da tela do usuário:
DPR: 2
Essa dica é útil ao selecionar fontes de imagem que correspondem à densidade de pixels de uma tela, como os descritores x fazem no atributo srcset.
Largura
A dica Width aparece em solicitações de recursos de imagem disparadas por tags <img> ou
<source> usando o atributo
sizes.
sizes informa ao navegador qual será o tamanho extrínseco do recurso;
Width usa esse tamanho extrínseco para solicitar uma imagem com um tamanho intrínseco que
seja ideal para o layout atual.
Por exemplo, digamos que um usuário solicite uma página com uma tela de 320 pixels CSS de largura e um DPR de 2. O dispositivo carrega um documento com um elemento <img> que contém
um valor do atributo sizes de 85vw (ou seja, 85% da largura da janela de visualização para todos os tamanhos de tela. Se a dica Width tiver sido ativada, o cliente vai enviar
essa dica Width ao servidor com a solicitação do src do <img>:
Width: 544
Nesse caso, o cliente está sugerindo ao servidor que uma largura intrínseca ideal para a imagem solicitada seria 85% da largura da janela de visualização (272 pixels) multiplicada pelo DPR da tela (2), o que equivale a 544 pixels.
Essa dica é especialmente útil porque não considera apenas a largura da tela corrigida pela densidade, mas também reconcilia essa informação crítica com o tamanho extrínseco da imagem no layout. Isso dá aos servidores a oportunidade de negociar respostas de imagem ideais para a tela e o layout.
Content-DPR
Você já sabe que as telas têm uma proporção de pixels do dispositivo, mas os recursos também têm proporções de pixels próprias. Nos casos de uso mais simples de seleção de recursos, as proporções de pixels entre dispositivos e recursos podem ser as mesmas. Mas! Nos casos em que os cabeçalhos DPR e Width estão em uso, o tamanho extrínseco de um recurso pode produzir cenários em que os dois diferem. É aí que entra a dica Content-DPR.
Ao contrário de outras dicas de cliente, Content-DPR não é um cabeçalho de solicitação para ser usado por
servidores, mas sim um cabeçalho de resposta que os servidores precisam enviar sempre que as dicas DPR e
Width são usadas para selecionar um recurso. O valor de Content-DPR precisa ser o resultado desta equação:
Content-DPR = [Tamanho do recurso de imagem selecionado] / ([Width] / [DPR])
Quando um cabeçalho da solicitação Content-DPR é enviado, o navegador sabe como dimensionar a imagem de acordo com a proporção de pixels do dispositivo da tela e o layout. Sem ele, as imagens podem não ser dimensionadas corretamente.
Device-Memory
Tecnicamente parte da API Device Memory, Device-Memory revela a
quantidade aproximada de
memória
que o dispositivo atual tem em GiB:
Device-Memory: 2
Um possível caso de uso dessa dica seria reduzir a quantidade de JavaScript enviada aos navegadores em dispositivos com memória limitada, já que o JavaScript é o tipo de conteúdo mais intensivo em recursos que os navegadores normalmente carregam. Ou você pode enviar imagens com DPR mais baixo, já que elas usam menos memória para decodificar.
Dicas de rede
A API Network Information oferece outra categoria de dicas de cliente que descrevem o desempenho da conexão de rede do usuário. Na minha opinião, essas são as dicas mais úteis. Com eles, podemos personalizar as experiências dos usuários mudando a forma como entregamos recursos aos clientes em conexões lentas.
RTT
A dica RTT fornece o tempo de retorno aproximado, em milissegundos, na camada de aplicativo. A dica RTT, ao contrário do RTT da camada de transporte, inclui o tempo de processamento do servidor.
RTT: 125
Essa dica é útil devido à função que a latência desempenha no desempenho do carregamento.
Usando a dica RTT, podemos tomar decisões com base na capacidade de resposta da rede, o que ajuda a acelerar a entrega de uma experiência completa (por exemplo, omitindo algumas solicitações).
Downlink
Embora a latência seja importante no desempenho de carregamento, a largura de banda também é influente. A dica Downlink, expressa em megabits por segundo (Mbps), revela a velocidade de download aproximada da conexão do usuário:
Downlink: 2.5
Junto com RTT, Downlink pode ser útil para mudar a forma como o conteúdo é
entregue aos usuários com base na qualidade de uma conexão de rede.
ECT
A dica ECT significa Tipo de conexão vigente. O valor é um de uma lista enumerada de tipos de conexão, cada um descrevendo uma conexão dentro de intervalos especificados de valores RTT e Downlink.
Esse cabeçalho não explica qual é o tipo de conexão real. Por exemplo, ele não informa se o gateway é uma torre de celular ou um ponto de acesso Wi-Fi. Em vez disso, ele analisa a latência e a largura de banda da conexão atual e determina a qual perfil de rede ela mais se assemelha. Por exemplo, se você se conectar
por Wi-Fi a uma rede lenta, ECT poderá ser preenchido com um valor de 2g,
que é a aproximação mais próxima da conexão efetiva:
ECT: 2g
Os valores válidos para ECT são 4g, 3g, 2g e slow-2g. Essa dica pode ser usada como ponto de partida para avaliar a qualidade da conexão e, posteriormente, refinada usando as dicas RTT e Downlink.
Save-Data
Save-Data não é tanto uma dica que descreve as condições da rede, mas sim uma preferência do usuário que afirma que as páginas devem enviar menos dados.
Prefiro classificar Save-Data como uma dica de rede porque muitas das coisas que você faria com ela são semelhantes a outras dicas de rede. Os usuários também podem ativar esse recurso em ambientes de alta latência/baixa largura de banda. Essa dica, quando
presente, sempre tem esta aparência:
Save-Data: on
Aqui no Google, já falamos sobre o que você pode fazer com o
Save-Data.
O impacto que ele pode ter no desempenho é significativo. É um sinal em que os usuários
estão literalmente pedindo para você enviar menos coisas! Se você ouvir e agir de acordo com esse
indicador, os usuários vão gostar.
Como tudo se junta
O que você faz com as dicas de cliente depende de você. Como eles oferecem muitas informações, você tem várias opções. Para ter algumas ideias, vamos ver o que as dicas de cliente podem fazer pela Sconnie Timber, uma empresa fictícia de madeira localizada no Upper Midwest rural. Como costuma acontecer em áreas remotas, as conexões de rede podem ser instáveis. É aqui que uma tecnologia como as dicas de cliente pode fazer a diferença para os usuários.
Imagens responsivas
Todos os casos de uso de imagens responsivas, exceto os mais simples, podem ficar complicados. E se você tiver vários tratamentos e variantes das mesmas imagens para diferentes tamanhos de tela e formatos? Essa marcação fica muito complicada muito
rápido.
É fácil errar, esquecer ou entender mal conceitos importantes, como sizes.
Embora <picture> e srcset sejam ferramentas incríveis, elas podem levar muito tempo para serem desenvolvidas e mantidas em casos de uso complexos. Podemos automatizar a geração de marcações, mas isso também é difícil porque a funcionalidade <picture> e srcset é complexa o suficiente para que a automação seja feita de uma forma que mantenha a flexibilidade oferecida.
As dicas de cliente podem simplificar isso. Negociar respostas de imagem com dicas do cliente pode ser algo assim:
- Se aplicável ao seu fluxo de trabalho, primeiro selecione um tratamento de imagem (ou seja, imagens dirigidas por arte) marcando a dica
Viewport-Width. - Selecione uma resolução de imagem marcando a dica
Widthe a dicaDPR, e escolha uma origem que se ajuste ao tamanho do layout e à densidade da tela da imagem (semelhante a como os descritoresxewfuncionam emsrcset). - Selecione o formato de arquivo mais adequado compatível com o navegador (algo que o
Acceptajuda a fazer na maioria dos navegadores).
No caso do meu cliente fictício de uma empresa madeireira, desenvolvi uma rotina simples de seleção de imagens responsivas em PHP que usa dicas de cliente. Isso significa que, em vez de enviar essa marcação para todos os usuários:
<picture>
<source
srcset="
company-photo-256w.webp 256w,
company-photo-512w.webp 512w,
company-photo-768w.webp 768w,
company-photo-1024w.webp 1024w,
company-photo-1280w.webp 1280w
"
type="image/webp"
/>
<img
srcset="
company-photo-256w.jpg 256w,
company-photo-512w.jpg 512w,
company-photo-768w.jpg 768w,
company-photo-1024w.jpg 1024w,
company-photo-1280w.jpg 1280w
"
src="company-photo-256w.jpg"
sizes="(min-width: 560px) 251px, 88.43vw"
alt="The Sconnie Timber Staff!"
/>
</picture>
Consegui reduzir para o seguinte com base no suporte individual do navegador:
<img
src="/image/sizes:true/company-photo.jpg"
sizes="(min-width: 560px) 251px, 88.43vw"
alt="SAY CHEESY PICKLES."
/>
Neste exemplo, o URL /image é um script PHP seguido de parâmetros
reescritos por
mod_rewrite. Ele usa um nome de arquivo de imagem e parâmetros adicionais para ajudar um script de back-end a escolher a melhor imagem nas condições especificadas.
Sinto que sua primeira pergunta é: "Mas isso não é apenas reimplementar <picture> e srcset no back-end?"
De certa forma, sim, mas com uma distinção importante: quando um aplicativo usa dicas de cliente para criar respostas de mídia, a maior parte (se não todo) do trabalho é muito mais fácil de automatizar, o que pode incluir um serviço (como uma CDN) que pode fazer isso em seu nome. Já com as soluções em HTML, é necessário escrever uma nova marcação para atender a cada caso de uso. Claro, você pode automatizar a geração de marcações. No entanto, se o design ou os requisitos mudarem, é provável que você precise revisar sua estratégia de automação no futuro.
Com as dicas de cliente, é possível começar com uma imagem de alta resolução e sem perdas que pode ser redimensionada dinamicamente para ser ideal para qualquer combinação de tela e layout. Ao contrário de srcset, que exige que você enumere uma lista fixa de possíveis candidatos a imagens para o navegador escolher, essa abordagem pode ser mais flexível. Enquanto srcset força você a oferecer aos navegadores um conjunto aproximado de variantes, digamos, 256w, 512w, 768w e 1024w, uma solução com tecnologia de dicas de cliente HTTP pode disponibilizar todas as larguras, sem uma grande quantidade de marcação.
Claro que você não precisa escrever a lógica de seleção de imagens. A Cloudinary usa dicas de cliente para criar respostas de imagem quando você usa o parâmetro w_auto e observou que os usuários medianos baixaram 42% menos bytes ao usar navegadores compatíveis com dicas de cliente.
Mas cuidado! As mudanças na versão para computador do Chrome 67 removeram o suporte para dicas de cliente de origem cruzada. Felizmente, essas restrições não afetam as versões móveis do Chrome, e serão removidas completamente para todas as plataformas quando o trabalho na Feature Policy for concluído.
Ajudar usuários em redes lentas
O desempenho adaptável é a ideia de que podemos ajustar a forma como entregamos recursos com base nas informações que as dicas de cliente disponibilizam para nós, especificamente informações sobre o estado atual da conexão de rede do usuário.
No site da Sconnie Timber, tomamos medidas para reduzir a carga quando as redes estão lentas. Para isso, examinamos os cabeçalhos Save-Data, ECT, RTT e Downlink no código do back-end. Quando isso é feito, geramos uma pontuação de qualidade da rede que podemos usar para determinar se devemos intervir para melhorar a experiência do usuário. Essa pontuação varia entre 0 e 1, em que 0 é a pior qualidade de rede possível e 1 é a melhor.
Inicialmente, verificamos se Save-Data está presente. Se for, a pontuação será definida como 0, já que presumimos que o usuário quer que façamos o que for necessário para tornar a experiência mais leve e rápida.
No entanto, se Save-Data estiver ausente, vamos ponderar os valores das dicas ECT, RTT e Downlink para calcular uma pontuação que descreve a qualidade da conexão de rede. O código-fonte da geração de pontuação de rede está disponível no GitHub. A conclusão é que, se usarmos as dicas relacionadas à rede de alguma forma, poderemos melhorar as experiências para quem está em redes lentas.
Quando os sites se adaptam às informações fornecidas pelas dicas de cliente, não precisamos adotar uma abordagem de "tudo ou nada". Podemos decidir de forma inteligente quais recursos enviar. Podemos modificar nossa lógica de seleção de imagens responsivas para enviar imagens de qualidade inferior para uma determinada tela e acelerar o desempenho do carregamento quando a qualidade da rede é baixa.
Neste exemplo, podemos ver o impacto que as dicas de cliente têm quando se trata de melhorar o desempenho dos sites em redes mais lentas. A seguir, há um diagrama em cascata do WebPagetest de um site em uma rede lenta que não se adapta às dicas de cliente:
Agora, uma cascata para o mesmo site na mesma conexão lenta, mas desta vez, o site usa dicas de cliente para eliminar recursos não essenciais da página:
As dicas de cliente reduziram o tempo de carregamento da página de mais de 45 segundos para menos de um décimo desse tempo. Os benefícios das dicas de cliente nesse cenário não podem ser enfatizados o suficiente e podem ser uma grande vantagem para usuários que buscam informações importantes em redes lentas.
Além disso, é possível usar dicas de cliente sem prejudicar a experiência
em navegadores que não são compatíveis com elas. Por exemplo, se quisermos ajustar a entrega de recursos usando o valor da dica ECT e ainda oferecer a experiência completa para navegadores sem suporte, podemos definir um valor padrão de substituição assim:
// Set the ECT value to "4g" by default.
$ect = isset($_SERVER["HTTP_ECT"]) ? $_SERVER["HTTP_ECT"] : "4g";
Aqui, "4g" representa a conexão de rede de mais alta qualidade que o cabeçalho ECT descreve. Se inicializarmos $ect como "4g", os navegadores que não oferecem suporte a dicas de cliente não serão afetados. Ativar FTW!
Cuidado com os caches!
Sempre que você mudar uma resposta com base em um cabeçalho HTTP, é preciso saber como os caches vão processar buscas futuras desse recurso. O Vary
cabeçalho é
indispensável aqui, porque ele associa entradas de cache ao valor dos cabeçalhos de solicitação
fornecidos a ele. Em outras palavras, se você modificar qualquer resposta com base em um determinado cabeçalho da solicitação HTTP, quase sempre inclua esse cabeçalho em Vary desta forma:
Vary: DPR, Width
No entanto, há uma grande ressalva: nunca Vary respostas
armazenáveis em cache em um cabeçalho que muda com frequência (como Cookie), porque esses
recursos se tornam efetivamente não armazenáveis em cache. Sabendo disso, talvez seja melhor evitar
Vary em cabeçalhos de dicas de cliente, como RTT ou Downlink, porque esses são
fatores de conexão que podem mudar com frequência. Se quiser modificar
respostas nesses cabeçalhos, considere usar apenas o cabeçalho ECT, que vai
minimizar falhas de cache.
É claro que isso só se aplica se você estiver armazenando uma resposta em cache.
Por exemplo, não armazene em cache recursos HTML se o conteúdo deles for dinâmico, porque isso pode prejudicar a experiência do usuário em visitas repetidas. Nesses casos, fique à vontade para modificar essas respostas com base no que você achar necessário, sem se preocupar com Vary.
Dicas de cliente em service workers
A negociação de conteúdo não é mais apenas para servidores. Como os service workers atuam
como proxies entre clientes e servidores, você tem controle sobre como os recursos
são entregues via JavaScript. Isso inclui dicas de cliente. No evento fetch do service worker, use o método request.headers.get do objeto event para ler os cabeçalhos de solicitação de um recurso desta forma:
self.addEventListener('fetch', (event) => {
let dpr = event.request.headers.get('DPR');
let viewportWidth = event.request.headers.get('Viewport-Width');
let width = event.request.headers.get('Width');
event.respondWith(
(async function () {
// Do what you will with these hints!
})(),
);
});
Qualquer cabeçalho de dica de cliente que você ativar pode ser lido dessa forma. Mas essa não é a única maneira de conseguir algumas dessas informações. As dicas específicas da rede podem ser lidas nestas propriedades equivalentes do JavaScript no objeto navigator:
| Dica de cliente | Equivalente em JS |
|---|---|
| `ECT` | `navigator.connection.effectiveType` |
| `RTT` | `navigator.connection.rtt` |
| `Save-Data` | `navigator.connection.saveData` |
| `Downlink` | `navigator.connection.downlink` |
| `Device-Memory` | `navigator.deviceMemory` |
Como essas APIs não estão disponíveis em todos os lugares, é necessário verificar o recurso com o
operador in:
if ('connection' in navigator) {
// Work with netinfo API properties in JavaScript!
}
Aqui, você pode usar uma lógica semelhante à que usaria no servidor, mas não precisa de um servidor para negociar conteúdo com dicas de cliente. Os service workers sozinhos têm o poder de tornar as experiências mais rápidas e resilientes devido à capacidade adicional de veicular conteúdo quando o usuário está off-line.
Conclusão
Com as dicas de cliente, podemos tornar as experiências mais rápidas para os usuários de uma forma totalmente progressiva. Podemos veicular mídia com base nos recursos do dispositivo do usuário de uma forma que facilita a veiculação de imagens responsivas em vez de depender de <picture> e srcset, especialmente para casos de uso complexos. Isso nos permite não apenas reduzir o tempo e o esforço no desenvolvimento, mas também otimizar recursos, principalmente imagens, de uma forma que segmenta as telas dos usuários com mais precisão do que
E, talvez mais importante, podemos detectar conexões de rede ruins e reduzir a diferença para os usuários modificando o que enviamos e como enviamos. Isso pode ajudar muito a facilitar o acesso aos sites para usuários em redes instáveis. Combinados com service workers, podemos criar sites incrivelmente rápidos que ficam disponíveis off-line.
Embora as dicas de cliente estejam disponíveis apenas no Chrome e em navegadores baseados no Chromium, é possível usá-las de uma forma que não prejudique os navegadores que não oferecem suporte a elas. Use dicas de cliente para criar experiências verdadeiramente inclusivas e adaptáveis que conheçam os recursos do dispositivo de cada usuário e as redes a que eles se conectam. Esperamos que outros fornecedores de navegadores vejam o valor deles e mostrem a intenção de implementar.
Recursos
- Imagens responsivas automáticas com dicas do cliente
- Dicas de cliente HTTP e imagens responsivas: o que mudou no Chrome 67
- Receba uma dica (de cliente)! (Apresentações)
- Como entregar aplicativos rápidos e leves com
Save-Data
Agradecemos a Ilya Grigorik, Eric Portis, Jeff Posnick, Yoav Weiss e Estelle Weyl pelo feedback e pelas edições valiosas neste artigo.