Em um navegador, é melhor usar uma planilha enorme ou muitos (10000) PNGs diferentes?

33

Estou criando um jogo no jQuery, onde uso cerca de 10000 peças 32x32. Até agora, eu tenho usado todos eles separadamente (sem folha de sprite). Um mapa médio usa cerca de 2000 blocos (às vezes reutiliza PNGs, mas todas divs separadas) e o desempenho varia de estável (Chrome) a um pouco lento (Firefox). Cada uma dessas divs é posicionada absolutamente usando CSS. Eles não precisam ser atualizados a cada tick, apenas quando um novo mapa é carregado.

Seria melhor para o desempenho usar métodos de planilha para as divs usando o posicionamento em segundo plano CSS, como o gameQuery faz?

Agradeço antecipadamente!

usuario
fonte
3
Onde diabos você precisa de 10 000 peças para o mapa? Sugiro que você não faça upload / desenhe todo o mapa no lado do usuário. Mostre apenas uma parte visível. Quando o usuário se mover, carregue a próxima seção. A maneira como todos os gráficos 3D funcionam.
Deele
Um mapa médio usa 2000 blocos diferentes ou apenas 2000 blocos totais? Qual o tamanho dos mapas que você está criando?
Nick Larsen
Você já pensou em usar uma ou algumas imagens maiores como plano de fundo e executar a detecção de colisão poligonal para limites?
SAHornickel

Respostas:

50

Minha sugestão

Muitos PNGs pequenos adicionarão muita sobrecarga de rede (devido ao tamanho das solicitações HTTP, mas também ao cabeçalho PNG e, provavelmente ainda mais importante, à incapacidade de compactar com eficiência). Por outro lado, um PNG muito grande tem os inconvenientes que leva algum tempo para carregar e precisa permanecer permanentemente na memória (40 megabytes para 10.000 blocos) em um pedaço contínuo de memória.

Eu recomendo o meio termo: vários PNGs de tamanho razoável, por exemplo, 1024 blocos de tamanho 32 × 32 . Talvez agrupados por tema (por exemplo, um PNG com ladrilhos da floresta, um com ladrilhos de montanha, outro com ladrilhos da cidade - não sei o tema do seu jogo, mas você entendeu).

Nota sobre a eficiência do cache

Devido à eficiência do acesso à memória, você nunca deve tornar suas planilhas muito grandes. A combinação de blocos de uma imagem de 128 × 8192 sempre será mais rápida do que a combinação de uma imagem de 8192 × 128.

Imagine que você deseja mesclar o primeiro bloco em uma imagem de 8192 × 128. Por uma questão de simplicidade, suponha que 1 pixel seja 1 byte. As duas primeiras linhas de pixels são dispostas dessa maneira (as células contêm seu número de bytes na memória):

┌────┬────┬───┬────┬──────────┬─────┐
  0   1 │...│ 31    ....    8191 1st line of pixels: bytes 0 to 8191
├────┼────┼───┼────┼──────────┼─────┤
81928193│...│8223   ....   16383 2nd line of pixels: bytes 8192 to 16383
├────┼────┼───┼────┼──────────┼─────┤
 ..  .. │...│ ..    ....    ... 

Portanto, para classificar a primeira linha do primeiro título, o mecanismo do navegador recuperará bytes 0para31 . Para blit a segunda linha , ele irá recuperar bytes 8192para8223 , e assim por diante até a linha 32 onde bytes 253952para253983 são recuperados.

O número total de bytes processados ​​será 32 × 32. No entanto, o intervalo total de memória é superior a 253984 bytes. Em uma CPU moderna, isso significa 32 ou 33 paradas de cache . Por outro lado, se a imagem tivesse 128 × 8192, o intervalo de memória seria de apenas 4000 bytes, o que significa não mais que duas paradas de cache.

Como as CPUs de hoje são muito rápidas, as paradas de cache são muito caras e paralisam os cálculos. Portanto, usar uma imagem de 128 × 8192 em vez de uma imagem de 8192 × 128 é potencialmente 8 vezes mais rápido, pelo menos em teoria. Na prática, isso dependerá de como a cegueira é implementada: é possível que o próprio mecanismo subjacente divida as imagens em blocos para reduzir o problema.

Isso não é fácil de explicar corretamente e eu não esperava elaborar muito. Eu espero que faça sentido!

sam hocevar
fonte
4
"Observe também que, devido à eficiência do acesso à memória, você nunca deve tornar suas planilhas muito amplas. A combinação de ladrilhos de uma imagem de 128 × 8192 será sempre mais rápida do que a partir de uma imagem de 8192 × 128". - boa curiosidade, você elaboraria por favor? :)
Grimshaw
@ DevilWithin: Eu tentei explicar o problema; deixe-me saber se estou sendo claro o suficiente!
23411 Samurai Hocevar #
O material da eficiência do cache é fascinante. Você tem algum número sobre a diferença que isso faz em relação à taxa de quadros?
Gregory Avery-Weir
Quer se trate de um problema, parece que aplicação específica, mas se API como OpenGL ato em texturas que maneira, com certeza é importante levar isso em consideração, graças :)
Grimshaw
2
@DevilWithin: o que escrevi é válido apenas para uma CPU - uma GPU, sendo massivamente paralela, tem configurações de cache muito diferentes e armazenará texturas usando seu próprio formato interno, otimizado para acesso aleatório. Esta é a razão pela qual texturas quadradas, com potência de duas, são recomendadas no OpenGL, e eu seguiria essa regra também para conjuntos de peças.
sam hocevar 3/11
5

Uma grande planilha (provavelmente) oferecerá melhor desempenho, simplesmente porque uma das maiores causas de atraso é a viagem de ida e volta da solicitação do navegador para o servidor para o navegador. 10.000 chamadas HTTP levarão muito, muito mais tempo do que uma chamada HTTP que retorna um arquivo 10.000 maior.

Pode haver outras coisas que você pode usar para diminuir o atraso, dependendo da estrutura do jogo e do HTML que você está criando.

thedaian
fonte