Trabalhar com imagens pode introduzir problemas de performance rapidamente se você não tomar cuidado. Mesmo um pequeno gráfico em um formato compactado, como JPG ou PNG, pode se transformar em um bitmap grande quando decodificado para exibição.Se você não for eficiente ao usar gráficos, poderá ter problemas de memória que prejudicam a performance do app e de outros apps no dispositivo. Siga estas práticas recomendadas para garantir que o app tenha a melhor performance.
Usar bibliotecas de carregamento de imagens
É possível melhorar a eficiência do app usando bibliotecas de carregamento de imagens como Coil (para projetos Kotlin-first) ou Glide (para projetos Java). Essas bibliotecas reduzem o uso de memória do app fazendo coisas como armazenar imagens em cache, redimensionar gráficos quando necessário e reciclar objetos gráficos.
Redimensionar imagens quando apropriado
Use o tamanho da imagem adequado às suas necessidades. Por exemplo, nunca carregue uma imagem grande em uma miniatura pequena. Em vez disso, use um método
como inSampleSize para carregar uma versão da imagem com nova amostragem.
As bibliotecas de carregamento de imagens, como Coil e Glide, processam essa nova amostragem automaticamente por padrão. É possível configurar as estratégias de subamostragem usando ImageLoader (para Coil) ou DownsampleStrategy (para Glide).
Forneça recursos alternativos para diferentes tamanhos de tela
Se você estiver enviando imagens com seu app, forneça recursos de tamanhos diferentes para resoluções de dispositivo distintas. Isso pode ajudar a reduzir o tamanho do download do app em dispositivos e melhorar a performance, já que uma imagem de resolução menor vai ser carregada em um dispositivo de resolução mais baixa. Para saber mais sobre como fornecer bitmaps alternativos para diferentes tamanhos de dispositivo, consulte a documentação alternativa de bitmap.
Não aplique padding diretamente
Às vezes, é necessário adicionar padding a uma imagem. Por exemplo, talvez você queira que a imagem seja cercada por uma borda transparente para letterboxing.
Nessas situações, não adicione o padding diretamente à imagem, mudando
as dimensões dela. Em vez disso, deixe as dimensões da imagem como estão,
e ajuste a localização dela na tela usando InsetDrawable.
Como alternativa, você pode adicionar padding ao elemento combinável ou à visualização que contém a imagem.
Escolha o formato de pixel certo
Equilibre a memória e a qualidade escolhendo o formato de pixel certo. Use RGB_565 quando não precisar de transparência. Esse formato usa metade da memória do formato ARGB_8888 padrão.
No Glide, é possível configurar isso usando DecodeFormat. No Coil, you can
use a bitmapConfig propriedade.
Use vetores sempre que possível
Para imagens compostas de formas geométricas, um gráfico vetorial é muito menor que um bitmap e é dimensionado sem problemas para qualquer densidade de exibição. Quando adequado, use elementos
como ShapeDrawable para representar gráficos.
Libere e reutilize bitmaps quando possível
Arquivos gráficos grandes podem ocupar muita memória. Para reduzir o impacto deles, libere ou reutilize os objetos gráficos sempre que possível.
Se você usar uma biblioteca de carregamento de imagens, libere bitmaps para o pool gerenciado da biblioteca quando não precisar mais deles. A biblioteca pode reutilizar os objetos quando necessário e mantém um buffer de memória disponível para necessidades futuras.
Se você estiver gerenciando gráficos manualmente, libere
bitmaps quando terminar de usá-los chamando Bitmap.recycle
e descartando imediatamente a referência Bitmap, em vez
de depender da coleta de lixo.
Outras dicas e truques
Esta seção lista algumas outras maneiras de melhorar a performance do app ao processar gráficos.
Não empacote imagens grandes com o arquivo AAB/APK
Uma das principais causas do tamanho grande de download do app são os gráficos empacotados dentro do arquivo AAB ou APK. Use a ferramenta APK Analyzer para garantir que você não esteja empacotando arquivos de imagem maiores do que o necessário. Reduza os tamanhos ou considere colocar as imagens em um servidor e só fazer o download delas quando necessário.
Encontrar bitmaps redundantes
Se você tiver várias cópias da mesma imagem, isso desperdiça memória. É possível usar o profiler do Android Studio para identificar gráficos redundantes. Use o heap dump analyzer para capturar um heap dump e filtre os resultados escolhendo a duplicate bitmaps configuração.
Ao usar ImageBitmap, chame prepareToDraw antes de desenhar
Ao usar ImageBitmap, para iniciar o processo de upload da textura para a
GPU, chame ImageBitmap#prepareToDraw() antes da renderização real. Isso
ajuda a GPU a preparar a textura e melhorar a performance da exibição de
uma imagem na tela. A maioria das bibliotecas de carregamento de imagem já faz essa otimização, mas se você estiver trabalhando com a classe ImageBitmap por conta própria, é importante se lembrar disso.
Prefira transmitir um Int DrawableRes ou URL como parâmetros para o elemento combinável em vez de Painter
Devido às complexidades de lidar com imagens (por exemplo, escrever uma função equals
para Bitmaps seria computacionalmente caro), a API Painter não é
marcada explicitamente como estável com a anotação @Stable. As classes instáveis podem levar a recomposições desnecessárias porque o compilador não pode inferir com facilidade se os dados mudam.
Portanto, recomendamos transmitir um URL ou um ID de recurso drawable como parâmetro aos elementos de composição, em vez de transmitir um Painter como parâmetro.
// Prefer this:
@Composable
fun MyImage(url: String) {
}
// Over this:
@Composable
fun MyImage(painter: Painter) {
}
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- ImageBitmap versus ImageVector {:#bitmap-vs-vector}
- Salvar o estado da interface no Compose
- Fases do Jetpack Compose