Confronto de Desempenho de Efeitos de Imagem da Web
Publicados: 2022-03-10À medida que os navegadores melhoram constantemente suas habilidades de renderização gráfica, a capacidade de realmente projetar dentro deles está se tornando uma realidade. Algumas linhas de código agora podem ter um impacto visual rápido e dramático e permitir consistência sem muito esforço . E, como acontece com a maioria das coisas no desenvolvimento da Web, geralmente há muitas maneiras de obter o mesmo efeito.
Neste post, vamos dar uma olhada em um dos efeitos de imagem mais populares, tons de cinza, e avaliar a facilidade de implementação e as implicações de desempenho da tela HTML, SVG, filtros CSS e modos de mesclagem CSS. Qual deles vai ganhar?
Leitura adicional no SmashingMag:
- Confronto de Desempenho de Efeitos de Imagem da Web
- HTML5: os fatos e os mitos
- Redimensionamento de imagem eficiente com ImageMagick
- Técnicas inteligentes de otimização de JPEG
Os filtros na web funcionam como uma lente colocada sobre uma imagem. Eles são aplicados à imagem depois que o navegador renderiza o layout e a pintura inicial. Em navegadores de suporte, os filtros podem ser aplicados individualmente ou em camadas uns sobre os outros. Como eles podem ser aplicados como modificações de imagem após a renderização inicial e provavelmente são um aprimoramento, os filtros se degradam graciosamente simplesmente não sendo visíveis em navegadores que não os suportam.
Filtros CSS
Vamos começar com o método mais direto para produzir um efeito de escala de cinza: o filtro CSS humilde, mas poderoso.

Para conseguir esse efeito, adicionamos uma única linha de CSS: filter: grayscale(1)
. Esse filtro dessatura a imagem e pode ser usado com qualquer valor numérico ou baseado em porcentagem entre 0 e 1 (ou 0% a 100%). Nota: atualmente, os filtros para navegadores baseados em WebKit devem ser prefixados com -webkit-
. No entanto, uma solução como o Autoprefixer eliminaria a necessidade de adicioná-los manualmente.
Demonstração ao vivo – Filtro CSS
.cssfilter-gray { -webkit-filter: grayscale(1); background: url('img/bird.jpg'); filter: grayscale(1); }
Modo de mesclagem de fundo
Os modos de mesclagem CSS fornecem uma variedade infinita de opções para combinações de efeitos de imagem. Existem duas maneiras de usar modos de mesclagem: a propriedade mix-blend-mode
e a propriedade background-blend-mode
.
-
mix-blend-mode
é a propriedade que descreve como o elemento se misturará com o conteúdo por trás dele. -
background-blend-mode
é usado para elementos com vários planos de fundo e descreve a relação entre esses planos de fundo.
Usaremos o background-blend-mode: luminosity
para puxar os canais de luminosidade sobre um fundo cinza em nosso exemplo, resultando em uma imagem em tons de cinza. Uma coisa a notar é que a ordem do plano de fundo é constante: as imagens de plano de fundo devem sempre ser ordenadas antes de cores sólidas ou planos de fundo gradientes para que os efeitos sejam renderizados corretamente . A cor deve ser a última camada de fundo. Isso também é uma proteção contra navegadores mais antigos que não suportam background-blend-mode
– a imagem ainda será renderizada sem o efeito.
A única diferença com os modos de mesclagem e o filtro CSS é que agora temos vários planos de fundo e estamos usando background-blend-mode: luminosity
, que pega os valores de luminosidade da imagem superior (o testador de pássaros) e sobrepõe esses valores de brilho em um segundo plano de fundo cinza.
Demonstração ao vivo - Modo de mesclagem de fundo
.cssfilter-gray { background: url('img/bird.jpg'), gray; background-blend-mode: luminosity; }
No momento, essa é a opção mais nova e, portanto, menos suportada, embora ainda funcione bem no Chrome e no Firefox e tenha suporte parcial ao Safari. Observação: o Safari suporta todos os modos de mesclagem, exceto os modos de mesclagem baseados em HSL: matiz, saturação, cor e luminosidade.
Tela HTML5
HTML5 <canvas>
permite muita flexibilidade quando se trata de manipulação de imagens, porque temos acesso aos dados de cada pixel individual (especificamente através canvasContext.getImageData
) e podemos manipular cada um através de JavaScript. Este método, no entanto, é o mais complexo e vem com a maior sobrecarga. Ele também tem algumas nuances em problemas de origem cruzada devido a questões de segurança.
Para corrigir o erro de origem cruzada no Chrome, sua imagem precisará ser hospedada em um site compatível com compartilhamento de recursos de origem cruzada (CORS), como GitHub Pages ou Dropbox, e especificar crossOrigin="Anonymous"
. Veja o exemplo ao vivo para uma demonstração.
A maneira de obter um efeito de escala de cinza com <canvas>
é retirar os componentes vermelho, verde e azul de qualquer valor externo no valor do pixel, mantendo seu nível de luminosidade (brilho). Uma maneira de fazer isso é calcular a média dos valores RGB da seguinte forma: grayscale = (red + green + blue) / 3;
.

No exemplo abaixo, estamos utilizando os valores RGBa no formato (R,G,B,a)
nos dados da imagem; o canal vermelho é data[0]
, o canal verde é data[1]
e assim por diante. Em seguida, obtemos o nível de luminosidade de cada um desses canais (o brilho) e calculamos a média para transformar a imagem em tons de cinza.
Demonstração ao vivo – HTML5 Canvas
Filtro SVG
Os filtros SVG têm o suporte mais amplo (mesmo no Internet Explorer e Edge!) e também são (quase) tão fáceis de usar quanto os filtros CSS diretamente. Você pode usá-los com a mesma propriedade de filter
. Na verdade, os filtros CSS surgiram dos filtros SVG. Assim como na tela, os filtros SVG permitem transcender o plano plano dos efeitos bidimensionais, pois você pode aproveitar o sombreamento WebGL para criar resultados ainda mais complexos.
Existem algumas maneiras de aplicar um filtro SVG, mas neste caso ainda usaremos a propriedade filter
na imagem de fundo, assim como o exemplo do filtro CSS para consistência. A maior diferença com os filtros SVG é que precisamos ter o cuidado de incluir e vincular a esse filtro com o caminho adequado. Isso significa que precisamos importar o SVG na página acima do elemento em que estamos usando (o que pode ser facilitado usando o mecanismo de modelagem e as instruções de inclusão).
Demonstração ao vivo – Filtro SVG
<svg> <filter> <feColorMatrix type="saturate" values="0"/> </filter> </svg>
.svgfilter-gray { background: url('img/bird.jpg'); -webkit-filter: url(#grayscale-filter); filter: url(#grayscale-filter); }
Desempenho do filtro
Então, como isso se compara quando se trata de desempenho inicial de renderização? Fiz uma página de teste para cada um e usei o recurso de comparação WebPagetest no Chrome 47. Tendo em mente que cada teste deu resultados ligeiramente diferentes, a tendência geral pode ser resumida da seguinte forma:
Os métodos de filtro CSS, filtro SVG e modo de mesclagem CSS foram carregados em intervalos de tempo relativamente semelhantes. Às vezes, o filtro SVG era mais rápido que o modo de mesclagem CSS (mas sempre pouco) e vice-versa. O filtro CSS geralmente estava entre os mais rápidos para carregar, e o <canvas>
era sempre o mais lento. Este é o insight mais significativo obtido. O <canvas>
estava regularmente atrasado em relação aos outros métodos de renderização da imagem.
Para ser justo, eu também queria comparar o tempo de carregamento de várias imagens. Criei dez renderizações de cada (em vez de apenas uma) e executei os testes novamente:
Os resultados foram semelhantes (lembre-se de que houve pequenas variações em cada teste). O filtro CSS foi 0,1ms mais lento neste caso, mostrando que entre filtros CSS, modos de mesclagem e filtros SVG, os resultados são inconclusivos para o método mais rápido. No entanto, HTML5 <canvas>
ficou visivelmente atrasado em comparação.
Observando mais profundamente o tempo de carregamento da página por meio de renderização de JavaScript e tempo de renderização de pintura, você pode ver que essa tendência continua.

Tipo de filtro | Tempo para renderizar | Hora de pintar |
---|---|---|
Filtro CSS | 12,94 ms | 4,28 ms |
Modo de mesclagem CSS | 12,10 ms | 4,45 ms |
Filtro SVG | 14,77 ms | 5,80 ms |
Filtro de tela | 15,23 ms | 10,73 ms |
Novamente, <canvas>
levou mais tempo para renderizar e mais tempo para pintar, enquanto as duas opções de CSS foram as mais rápidas, com SVG no meio.
Esses resultados fazem sentido, porque <canvas>
está pegando cada pixel individual e realizando uma operação nele antes que possamos ver qualquer imagem. Isso exige muito poder de processamento no tempo de renderização. Embora normalmente os SVGs sejam usados para gráficos vetoriais, eu ainda os recomendo sobre <canvas>
ao lidar com efeitos de imagem raster. O SVG não é apenas mais rápido, mas também muito mais fácil de lidar e mais flexível dentro do DOM. Geralmente, os filtros CSS são ainda mais otimizados que os filtros SVG, pois historicamente são atalhos que emergem dos filtros SVG e, portanto, otimizados nos navegadores.
#Sem filtro
Que tal não usar filtro? Comparei nosso método geral mais rápido (adicionar um filtro CSS) com a edição de sua imagem no software de edição de fotos antes de carregá-la (usei o Preview no Mac OS X para remover a saturação). Ao pré-editar a imagem, encontrei uma melhoria de desempenho consistente de 0,1 ms em meus testes:
Conclusão
Os filtros de imagem são uma maneira divertida e eficaz de fornecer unidade visual e apelo estético na web. Tenha em mente que eles vêm com um pequeno impacto no desempenho, mas também com os benefícios do design rápido no navegador e a oportunidade de projetar interações.
Para efeitos de imagem simples, use filtros CSS, pois eles têm o suporte mais amplo e o uso mais simples. Para efeitos de imagem mais complexos, confira os filtros SVG ou modos de mesclagem CSS. Os efeitos de filtro SVG são particularmente bons por causa de seus recursos de manipulação de canal e feColorMatrix
. Os modos de mesclagem CSS também oferecem alguns efeitos visuais muito bons com elementos sobrepostos na página. Você pode usar modos de mesclagem semelhantes no SVG (como feBlend
), embora sejam semelhantes ao background-blend-mode
CSS no sentido de que a interação pertence ao próprio SVG e não aos elementos circundantes, como mix-blend-mode
permite. Só não use <canvas>
para filtros.