BLOG | NGINX

NGINX e NGINX Plus oferecem imagens responsivas sem dores de cabeça

NGINX-Parte-de-F5-horiz-preto-tipo-RGB
Miniatura de Liam Crilly
Liam Crilly
Publicado em 29 de setembro de 2016
Imagem de uma estante de revistas para um artigo sobre o uso do módulo NGINX Plus Image-Filter para gerar imagens responsivas para um web design mais responsivo.
Foto: Phil Roeder

Usando o módulo Image‑Filter e a tag srcset para redimensionar imagens rapidamente

O web design responsivo se tornou a norma para sites e aplicativos web modernos, proporcionando uma experiência consistente em uma ampla variedade de dispositivos e, ao mesmo tempo, otimizando a exibição para cada dispositivo. No entanto, os dispositivos modernos variam não apenas em termos de tamanho de tela, mas também de densidade de pixels. A tag img HTML5 fornece uma série de recursos que permitem ao navegador selecionar o ativo mais apropriado se o servidor fornecer diversas variantes. Se o site implantar vários tamanhos diferentes da mesma imagem, o navegador pode escolher o tamanho mais adequado ao seu ambiente atual.

Imagens responsivas podem, portanto, permitir que o navegador da web produza uma renderização que corresponda de perto à intenção do designer. Isso melhora a experiência do usuário, mas também coloca uma carga adicional nas equipes de desenvolvimento e operações, que agora precisam criar e implantar diversas variantes de ativos de imagem, bem como a imagem padrão.

Nesta postagem do blog, mostramos como usar o módulo Image‑Filter para NGINX e NGINX Plus para fornecer imagens responsivas sem a dor de cabeça de criar e gerenciar uma infinidade de variantes de ativos de imagem. Em vez disso, podemos implantar uma única versão de "origem" de cada imagem que o NGINX ou NGINX Plus redimensiona instantaneamente. As informações na postagem se aplicam tanto ao NGINX Open Source quanto ao NGINX Plus (exceto pelas instruções separadas em Instalando o módulo de filtro de imagem ); para resumir, nos referimos ao NGINX Plus em todo o texto.

O atributo srcset

A principal ferramenta para fornecer imagens responsivas é o atributo srcset da tag img do HTML5. Podemos usá-lo para especificar uma série de variantes de ativos de imagem para diferentes densidades de pixels e tamanhos de viewport. Viewport é um termo genérico para o espaço de exibição disponível para o navegador da web, seja em uma janela em um desktop ou em um aplicativo de tela cheia em um dispositivo móvel.

No exemplo a seguir, o atributo src define uma imagem padrão para navegadores que não oferecem suporte ao atributo srcset e o atributo srcset nomeia duas variantes: uma para telas com densidade de pixels padrão ( 1x ) e uma segunda para telas com densidade de pixels dupla, como telas Apple Retina™ e alguns monitores 4K ( 2x ).

< img src= "/images/mylogo-default.png" srcset= "/images/mylogo-density1.png 1x, /images/mylogo-density2.png 2x" >

O exemplo mais sofisticado a seguir define uma série de variantes de ativos de imagem a serem exibidas, de acordo com a largura da janela de visualização. O atributo sizes especifica que o navegador renderiza uma imagem em metade da janela de visualização se ela for mais larga que 10em e usa a janela de visualização inteira caso contrário. O navegador determina quanto espaço está disponível para a imagem e seleciona a variante de ativo de imagem que melhor se ajusta ao espaço disponível, normalmente “arredondando para cima” para a próxima largura (sufixo w ) e redimensionando internamente a imagem para preencher o espaço exatamente.

< img src= "/images/racecar-default.jpg" tamanhos= "(largura mínima: 10em) 50vw, 100vw" srcset= "/imagens/carro de corrida-100px.jpg 100w, /imagens/carro de corrida-225px.jpg 225w, /imagens/carro de corrida-450px.jpg 450w, /imagens/carro de corrida-675px.jpg 675w" >

Essa abordagem para fornecer imagens responsivas especificando uma variedade de variantes de ativos de imagem é fácil de codificar e altamente eficaz. No entanto, ele apresenta desafios em termos de criação e gerenciamento das próprias variantes de imagem. Você precisa fazer uma grande quantidade de redimensionamento de imagens de pré-produção e implantar um número muito maior de arquivos no servidor. Pode levar muito tempo para ajustar o número e o tamanho ideais de cada variante, o que dificulta o teste de acessibilidade de cada variante de ativo de imagem.

Para obter mais informações sobre o atributo srcset e outras técnicas para imagens responsivas, consulte esta ótima postagem do blog .

Instalando o módulo Image‑Filter

O procedimento para obter o módulo Image‑Filter é diferente para NGINX Plus e NGINX.

Instalando o módulo Image‑Filter para NGINX Plus

O módulo Image‑Filter está disponível como um módulo dinâmico gratuito para assinantes do NGINX Plus.

  1. Obtenha o módulo instalando-o do repositório NGINX Plus.

    Para sistemas Ubuntu e Debian:

    $ sudo apt-get install nginx-plus-module-image-filter

    Para sistemas RedHat, CentOS e Oracle Linux:

    $ sudo yum install nginx-plus-module-image-filter
  2. Habilite o módulo incluindo uma diretiva load_module para ele no contexto de nível superior (“principal”) do arquivo de configuração nginx.conf (ou seja, não nos contextos http ou stream ).

    load_module módulos/ngx_http_image_filter_module.so;
  3. Recarregue o NGINX Plus para carregar o módulo Image‑Filter na instância em execução.

    $ sudo nginx -s recarregar >

Instalando o módulo Image‑Filter para NGINX Open Source

A maneira mais fácil de instalar o módulo Image‑Filter é obtê-lo do repositório oficial do NGINX. Siga estas instruções para configurar seu sistema para acessar o repositório oficial do NGINX e depois instalá-lo com o gerenciador de pacotes do seu sistema operacional.

Para sistemas Ubuntu e Debian:

$ sudo apt-get install nginx-module-image-filter

Para sistemas Red Hat, CentOS e Oracle Linux:

$ sudo yum instalar filtro de imagem do módulo nginx

Após a instalação, siga as etapas 2 e 3 em Instalando o módulo de filtro de imagem para NGINX Plus para configurar o NGINX e recarregar.

Também é possível compilar o módulo Image‑Filter a partir do código-fonte e carregá-lo como um módulo compilado estaticamente ou dinâmico. Para obter detalhes, consulte o Guia de administração do NGINX Plus .

Correspondência do tamanho da imagem com a densidade de pixels

Com o módulo Image‑Filter, podemos criar e implementar uma única versão de “origem” de cada imagem e fazer com que o NGINX Plus a redimensione rapidamente para fornecer quaisquer variantes de tamanho solicitadas pelo navegador. Podemos ajustar páginas da web responsivas e imagens inteiramente dentro do código-fonte HTML, sem redimensionar e implantar manualmente as imagens em nosso servidor web.

Neste arquivo HTML de exemplo, definimos quatro variantes de imagem para dispositivos com diferentes densidades de pixels.

< html > < head > < title > Logotipo responsivo  title >  head > < body > < h2 > Seleção de logotipo com base na densidade de pixels  h2 > < img src= "/img400/mylogo.png" srcset= "/img400/mylogo.png 1x, /img800/mylogo.png 2x, /img1200/mylogo.png 3x, /img1600/mylogo.png 4x" >  body >  html >

Os diretórios /img400 , /img800 , /img1200 e /img1600 não existem de fato. Em vez disso, a seguinte configuração do NGINX Plus corresponde a solicitações de ativos prefixados com /img e as transforma em solicitações para redimensionar a imagem no nome do arquivo original (por exemplo, mylogo.png no HTML anterior).

servidor { ouvir 80;
raiz /var/www/public_html;

localização ~ ^/img([0-9]+)(?:/(.*))?$ {
alias /var/www/source_images/$2;
buffer_de_filtro_de_imagem 10M;
redimensionamento_de_filtro_de_imagem $1 -;
}
}

O bloco do servidor define como o NGINX Plus lida com solicitações HTTP de entrada. A diretiva listen informa ao NGINX Plus para escutar na porta 80 – o padrão para tráfego HTTP. A diretiva root especifica a localização deste site no disco. Neste exemplo simples, estamos usando um site estático hospedado pelo NGINX Plus, mas também é comum que o NGINX Plus atue como um proxy reverso para conteúdo dinâmico ou um conector de aplicativo como o FastCGI. Todos esses casos de uso podem aproveitar o módulo Image‑Filter conforme descrito aqui, implantando as imagens de origem no servidor NGINX Plus.

O bloco de localização usa uma expressão regular para corresponder a solicitações de ativos armazenados em qualquer diretório que comece com /img seguido por um ou mais dígitos. Os dígitos são capturados como variável $1 e o nome do arquivo que se segue é capturado como variável $2 . Em seguida, usamos a diretiva alias para atender a essa solicitação do diretório no disco que contém nossas imagens de origem. Observe que esse diretório não está no caminho raiz , portanto os clientes não podem solicitar as imagens de origem diretamente.

Como nossas imagens de origem provavelmente serão muito grandes, talvez com milhares de pixels de largura, precisamos garantir que o módulo Image‑Filter aloque memória suficiente para carregá-las e redimensioná-las. Neste exemplo, usamos a diretiva image_filter_buffer para oferecer suporte a arquivos de imagem de até 10 MB.

Por fim, a diretiva image_filter informa ao módulo Image‑Filter para redimensionar a imagem de origem para a largura capturada do sufixo do nome do diretório /img . O traço (‑) informa ao NGINX Plus para manter a proporção da imagem de origem.

Considerações para uso em produção

A configuração descrita em Correspondência do tamanho da imagem com a densidade de pixels pode fornecer qualquer variante de tamanho de uma imagem, dependendo do nome do diretório usado para solicitar a imagem. Entretanto, para um ambiente de produção, não queremos esperar que o servidor web redimensione as imagens para cada solicitação. Isso não é bom para a latência geral e também pode adicionar uma sobrecarga significativa à CPU.

A solução mais eficaz é armazenar em cache nossas variantes de imagem redimensionadas para que solicitações subsequentes para cada variante sejam atendidas pelo cache, sem passar pelo módulo Image‑Filter. Podemos conseguir isso com a configuração do NGINX Plus definindo um servidor virtual separado que executa o redimensionamento da imagem e envia solicitações de proxy para ele somente se o tamanho da imagem solicitado ainda não estiver no cache. Chamamos isso de servidor de imagem responsivo .

Uma configuração de produção do NGINX Plus com blocos de 'localização' para um servidor web front-end e um servidor de imagem responsivo. Para um web design mais responsivo, o servidor web armazena em cache as variantes de tamanho criadas pelo servidor de imagens usando o módulo Image-Filter.
Figura 1. Configuração de produção de um servidor de imagem responsivo com cache habilitado no servidor web frontend

Também devemos considerar as implicações de segurança de permitir solicitações arbitrárias para executar operações de redimensionamento de imagens. Ter o cache configurado não ajuda se um invasor fizer solicitações rápidas para variantes exclusivas de ativos de imagem, como /img1001/mylogo.png , /img1002/mylogo.png , /img1003/mylogo.png e assim por diante. Mesmo com um volume relativamente baixo de solicitações, esses ataques podem causar negação de serviço (DoS) devido à utilização excessiva da CPU. Para resolver isso, aplicamos um limite de taxa ao servidor de imagem responsivo, mas não ao servidor front-end que contém as variantes armazenadas em cache. A configuração a seguir estende a configuração em Correspondência do tamanho da imagem à densidade de pixels aplicando cache e limitação de taxa ao módulo Filtro de imagem.

proxy_cache_path /var/www/imgcache levels=1 keys_zone=resized:1m max_size=256m;
server {
listen 80;
root /var/www/public_html;

location ~ ^/img([0-9]+)(?:/(.*))?$ {
proxy_pass http://127.0.0.1:9001;
proxy_cache resized;
proxy_cache_valid 180m;
}
}

limit_req_zone "1" zone=2persec:32k rate=2r/s;

server {
listen 9001;
allow 127.0.0.1;
deny all;
limit_req zone=2persec burst=10;

localização ~ ^/img([0-9]+)(?:/(.*))?$ {
alias /var/www/source_images/$2;
image_filter_buffer 10M;
image_filter resize $1 -;
}
}

Começamos definindo a localização das nossas imagens em cache com a diretiva proxy_cache_path . O parâmetro keys_zone define uma zona de memória compartilhada para o índice de cache (chamado resized ) e aloca 1 MB, o que é suficiente para cerca de 8.000 imagens redimensionadas. O parâmetro max_size define o ponto em que o NGINX Plus começa a remover as imagens menos solicitadas recentemente do cache para abrir espaço para novos itens em cache.

A diretiva de localização para o servidor web frontend (aquele que escuta na porta 80) usa a diretiva proxy_pass para enviar solicitações prefixadas com /img para o servidor de imagem responsivo hospedado internamente (127.0.0.1:9001). A diretiva proxy_cache habilita o armazenamento em cache para esse local especificando o nome do cache ( redimensionado ) a ser usado para armazenar respostas do servidor de imagem responsivo. A diretiva proxy_cache_valid garante que as imagens redimensionadas sejam mantidas no cache por pelo menos 180 minutos (a menos que o cache tenha excedido max_size e elas estejam entre as menos solicitadas recentemente) e que quaisquer respostas errôneas do servidor de imagens responsivo não sejam armazenadas em cache.

Para uma descrição detalhada do cache, consulte Um guia para cache com NGINX e NGINX Plus .

Antes de definir o próprio servidor de imagem responsivo, especificamos um limite de taxa com a diretiva limit_req_zone . A diretiva não impõe um limite de taxa por si só – ela define um limite de taxa de duas solicitações por segundo que é então aplicado ao servidor de imagem responsivo incluindo a diretiva limit_req em seu bloco de servidor (veja o próximo parágrafo). Normalmente, um limite de taxa é vinculado a um atributo da solicitação, mas neste caso especificamos o valor de chave estática "1" para que o limite se aplique a todos os solicitantes. Definimos o tamanho da zona de memória compartilhada para o menor valor possível, 3 KB, porque nossa chave tem uma cardinalidade fixa de um.

O bloco do servidor para o servidor de imagem responsivo escuta na porta 9001. Incluímos as diretivas allow e deny para especificar que somente o localhost (o servidor web frontend) pode se conectar ao servidor de imagem responsivo. Em seguida, aplicamos o limite de taxa definido anteriormente incluindo a diretiva limit_req ; o parâmetro burst permite 10 solicitações simultâneas antes de impor o limite de taxa. Uma vez que o limite de taxa entra em vigor, solicitações excedentes são adiadas até que possam ser processadas dentro do limite.

O bloco de localização é idêntico ao de Correspondência do tamanho da imagem à densidade de pixels , mas agora é exercido somente quando a imagem solicitada não está no cache e enquanto o limite de taxa não foi excedido.

Nesta configuração básica, uma única instância do NGINX Plus atua como servidor web front-end e servidor de imagem responsivo. O processamento de imagens pode ser muito intensivo em termos computacionais, o que pode levar a cargas de trabalho extremamente altas e tornar o NGINX Plus sujeito a ataques DoS. Para evitar a situação em que o servidor web frontend não pode aceitar imediatamente novas solicitações porque todos os processos de trabalho estão ocupados com solicitações de redimensionamento de imagem, recomendamos executar uma instância separada do NGINX Plus dedicada ao processamento de imagens. Isso isola os processos de trabalho do servidor web front-end daqueles que realizam o processamento de imagens. Para executar uma instância separada do NGINX Plus no mesmo host, especifique um arquivo de configuração diferente na linha de comando:

$ sudo nginx -c /etc/nginx/resize-server.conf

Imagens responsivas em ação

A maneira mais eficaz de ver imagens responsivas em ação é observar um navegador tomando decisões sobre qual variante de imagem srcset usar conforme o tamanho da janela de visualização muda. Aqui está o código-fonte HTML de uma galeria de imagens simples. Observe que, para fins de demonstração, as variantes de tamanho são ligeiramente diferentes para cada imagem, criando muitos possíveis “pontos de interrupção” nos quais o navegador pode escolher uma variante diferente.

<!DOCTYPE html>
<HTML->>
<cabeça>
<título>Galeria de imagens responsivas</título>
</cabeça>
<corpo>
 
<h2>Galeria de imagens responsivas</h2>

<imagem origem="/img100/1-dominos.jpg" tamanhos="(largura mínima: 20em) 40vw, 100vw" srcset= "/img110/1-dominos.jpg 110w, /img210/1-dominos.jpg 210w, /img310/1-dominos.jpg 310w, /img410/1-dominos.jpg 410w, /img510/1-dominos.jpg 510w, /img610/1-dominos.jpg 610w" > < img src= "/img100/2-sign.jpg" sizes= "(largura mínima: 20em) 40vw, 100vw" srcset= "/img120/2-sign.jpg 120w, /img220/2-sign.jpg 220w, /img330/2-sign.jpg 330w, /img420/2-sign.jpg 420w, /img520/2-sign.jpg 520w, /img620/2-sign.jpg 620w" > < img src= "/img100/3-thruppence.jpg" sizes= "(largura mínima: 20em) 40vw, 100vw" srcset= "/img130/3-thruppence.jpg 130w, /img230/3-thruppence.jpg 230w, /img330/3-thruppence.jpg 330w, /img440/3-thruppence.jpg 440w, /img550/3-thruppence.jpg 550w, /img660/3-thruppence.jpg 660w" > < img src= "/img100/4-aces.jpg" sizes= "(largura mínima: 20em) 40vw, 100vw" srcset= "/img140/4-aces.jpg 140w, /img240/4-aces.jpg 240w, /img340/4-aces.jpg 340w, /img440/4-aces.jpg 440w, /img540/4-aces.jpg 540w, /img640/4-aces.jpg 640w" >  corpo >  html >

As capturas de tela abaixo mostram o conteúdo desta página da web em um navegador Chrome com o Inspetor aberto na guia Rede . A coluna Nome mostra o caminho de cada variante de imagem solicitada ao servidor, o que nos permite ver o tamanho escolhido sem precisar verificar os logs no servidor web.

Com a janela de visualização estreita na Figura 2, o navegador escolheu imagens entre 220 e 310 pixels de largura (os sufixos numéricos nos nomes do diretório /img na coluna Nome variam entre esses valores).

Figura 2. Galeria de imagens responsiva quando a janela de visualização é estreita

Quando ampliamos a janela do navegador na Figura 3, o navegador escolhe imagens entre 440 e 540 pixels de largura (as últimas quatro imagens listadas). O valor dessas imagens na coluna Iniciador é Outro .

Figura 3. Galeria de imagens responsiva quando a janela de visualização é mais ampla

Conclusão

Com o NGINX Plus e o módulo Image‑Filter, podemos fornecer o tamanho de imagem ideal para as condições atuais do navegador. E podemos fazer isso sem redimensionar imagens de pré-produção, processar em lote ou ter que gerenciar centenas de variantes de ativos de imagem no disco. Apenas mais uma maneira pela qual o NGINX Plus ajuda você a obter uma entrega de aplicativos perfeita.

Experimente você mesmo imagens responsivas com o NGINX Plus – comece seu teste gratuito de 30 dias hoje mesmo ou entre em contato conosco para discutir seus casos de uso .


"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."