Problema de emoji ao renderizar no webkit - Problema com a forma como o HTML é renderizado

Temos muitos usuários que usam dispositivos Apple e/ou navegadores baseados em WebKit que relatam problemas ao rolar os tópicos, a ponto de o fórum se tornar inutilizável.

Um exemplo, capturado em vídeo aqui.

Após muita investigação, parece que a causa mais provável é como o WebKit é… como posso dizer isso de forma branda… lixo no manuseio do redimensionamento de imagens.

No entanto, isso também levou à observação de como os emojis são renderizados no HTML cozido e eu gostaria de alguns esclarecimentos, pois talvez eu esteja perdendo alguma configuração que poderia ter feito para evitar isso.

Em verde, você pode ver o tamanho original do emoji.

Em azul/ciano/o que quer que seja, os atributos padrão adicionados pelo Discourse ao cozinhar o conteúdo.

Em vermelho, o CSS adicionado pelo plugin que escrevi que:

  • importa os emojis (são muitos)
  • adiciona alguns CSS personalizados para que eles renderizem corretamente, pois nem todos são “20 por 20”

Agora fiz um teste simples. Removi do campo cooked no banco de dados para esse tópico, todos os width="20" height="20" e pedi aos usuários para tentarem novamente e visualizarem o tópico, rolando, respondendo, mesmo que alguém esteja adicionando novas postagens, mas sem usar emojis para não injetar novamente esses dois atributos no HTML renderizado dos emojis.

Aparentemente, isso é o que estava causando os problemas no WebKit, pois todos os relatos que tenho confirmam que, agora que esses dois atributos foram removidos, não há problemas com a rolagem.

Portanto, há alguma maneira de impedir que o Discourse adicione esses parâmetros? Por que o Discourse assume que todo emoji terá “20x20” e, além disso, o impõe via atributo HTML em vez de usar CSS?

Obrigado

Consegui reproduzir no meu iPad, mas não no Chrome desktop.

Eu rolo para cima e a linha do tempo volta para a postagem anterior, dificultando rolar para passar e ir mais adiante na linha do tempo.

Mas tenho dificuldade em reproduzir isso de forma consistente. Fiquei preso na postagem nº 1955, mas depois que consegui rolar para cima passando dela, se eu voltasse e rolasse para cima novamente, não me bloqueava mais :thinking:

O motivo é que isso acontece toda vez que um novo emoji está sendo “carregado de forma preguiçosa” e os atributos de tamanho estão sendo renderizados.

Uma vez renderizado, o problema não acontece. Mas se você percorrer um tópico com muitas respostas e no qual os emojis são usados com bastante frequência, você verá constantemente esse comportamento acontecer e isso tornará o uso do Discourse impossível.

Conseguimos “corrigir” isso em nosso tema personalizado, mas acho que isso deve ser abordado no tema padrão também, ou melhor ainda, na função que processa as postagens, pois não vejo motivo para que esses atributos de HTML relacionados ao tamanho sejam aplicados em vez de usar CSS simples.

Acrescento que todos os navegadores para iOS parecem usar webkit, então será um problema principalmente para dispositivos Apple. Não sou um especialista nisso, então leve isso com uma pitada de sal. Mais testes seriam necessários.

1 curtida

Isso ocorre porque todos os emojis unicode padronizados são projetados para caber em um quadrado, e assumimos que os sites desejam que seus emojis tenham um tamanho consistente, de forma que funcionem ao lado de texto e outros emojis :teapot: se aquele bule fosse 50x50, ele criaria um grande espaço entre as linhas como este:

Há uma boa explicação de quando foi adicionado originalmente:

Com detalhes de apoio de Multimedia: Images - Learn web development | MDN

Quando os atributos width e height de uma imagem são incluídos em um elemento <img /> HTML, a proporção da imagem pode ser calculada pelo navegador antes que a imagem seja carregada. Essa proporção é usada para reservar o espaço necessário para exibir a imagem, reduzindo ou até mesmo prevenindo uma mudança de layout quando a imagem é baixada e exibida na tela. Reduzir a mudança de layout é um componente importante da boa experiência do usuário e do desempenho da web.

Enquanto as melhores práticas de desenvolvedor da última década podem ter recomendado omitir os atributos width e height de uma imagem em um elemento <img /> HTML, devido ao mapeamento de proporção, incluir esses dois atributos é considerado uma melhor prática de desenvolvedor.

Dito tudo isso, você tem um exemplo razoável de um caso em que o dimensionamento padrão não funcionará para todos os emojis… aquele antigo emoji de brinde é 3 vezes mais largo, então ele não se encaixa bem em um quadrado. Não é incomum que outros aplicativos limitem todos os emojis a quadrados, então não somos muito incomuns em nosso comportamento aqui (tanto Slack quanto Discord fazem isso, por exemplo)… mas alternativamente, poderíamos considerar permitir que emojis personalizados tenham dimensões opcionais definidas.

2 curtidas

Do lado do CSS, isso é facilmente implementado:

img.emoji {
  width: auto; /* substituindo width: 20px; */
  height: 20px;
  vertical-align: text-bottom;
}

(Veja DEV: add native lazy loading for emojis by rr-it · Pull Request #15830 · discourse/discourse · GitHub para explicação.)

O trabalho mais difícil está na parte de “emoji personalizado” e na renderização de emojis:

  • emoji personalizado precisa de um atributo extra para cada emoji: aspect-ratio (ou, como alternativa, height e width).
  • a renderização de emoji deve usar o novo atributo aspect-ratio para que emojis personalizados variem a width de acordo – height permanece em 20px.

Abordagem rápida e fácil para emojis personalizados:
Para emojis personalizados, defina height="20" apenas nas tags img e não defina width – descartando assim o benefício de definir aspect-ratio/width e height.
CSS: img.emoji { width: auto; }

2 curtidas