[Dúvida] Qual o melhor jeito de enviar imagens do backend para o frontend sem prejudicar o desempenho?
estou criando uma aplicação java - spring + angular, será algo como um marketplace, então terão várias imagens envolvidas em cada página, eu fiz uma implementação convertendo as imagens em base64 no backend e enviando para o front, onde ele converte o base64 em imagem, renderiza e exibe, até ai tudo funciona, o grande problema é que quando eu adiciono muitos produtos, a pagina demora muito para carregar, creio que por conta da renderização da imagem em base64
então aqui vem o ponto que estou precisando de ajuda
como eu posso enviar as imagens que estão na raiz do meu servidor, para o front, sem atrapalhar tanto o desempenho?
eu sou iniciante em aplicações fullstack e agradeço desde já toda a ajuda!
Você está convertendo um arquivo binário (imagem sla jpg) para TEXTO e convertendo texto em binário novamente?
Pode ter certeza que essa é uma péssima ideia.
Base64 só pode ser usado quando não há nenhuma outra alternativa viável. Como comunicar com um sistema externo legado que você não tem controle nenhum. Evite esse formato ao máximo.
Primeiro passo
Como você está armazenando essa imagem? Qual o real motivo do backend ter que processar isso?
Não há justificativa para o backend ou o frontend sequer tocar na imagem de um sistema seu.
Se a imagem estiver em um sistema de arquivos sirva a imagem direto do servidor WEB (nginx).
Como isso é feito em projetos reais?
Enviar imagens para o frontend é um problema que geralmente não resolvemos sozinhos. O mais comum é usar um serviço como o AWS S3.
Nesse tipo de solução o seu banco de dados persiste uma referência da imagem (pode ser um link) que está armazenado no AWS S3.
sequenceDiagram
Front-->>Server: HTTP request
Server-->>Database: Query
Database-)Server: Link da imagem
Server-)Front: Link da imagem
Front -->> S3: HTTP request
S3 -) Front: Imagem/jpeg
Esse esquema tem algumas vantagens:
- Evita a complexidade de ter que manusear imagens no seu backend.
- Economiza processamento e memória do seu servidor
- Economiza processamento e memória do seu banco de dados
- Você pode usar todos os recursos do S3 - Recursos de segurança - Integração automática com CDN, como o AWS CloudFront.
Em resumo:
Não desenvolva seu próprio serviço de imagens em um projeto real. Já trabalhei em um projeto de uma plataforma de ensino. Era tudo armazenado no S3. É seguro, confiável e escalável. Não tem opção melhor.
Sugestão: hospedar a imagem em um servidor de arquivos para isso, como um S3 na AWS por exemplo. Vc grava os dados no seu back e a imagem nesse local de repositório. No back (banco de dados) vc grava a URL da imagem do repositório e não o "arquivo" em si. No front vc faz o upload da imagem e usa um serviço (api) para enviar o binário dessa imagem para o repositório. Assim seu back não guarda dados de arquivo, nem seu banco de dados e na hora o usuário renderizar, ele recebe uma URL que irá carregar a imagem direto para ele, sem passar por sua camada de serviço.
Tenta de alguma forma servir arquivos estáticos, a maiora dos frameworks ja fornecem libraries pra esse tipo de ação, no django é servido praticamente automático, podendo utilizar local ,nao recomendo, ou buckets s3 tanto local utilizando minio em docker.
settings.py
STATIC_URL = "static"
STATIC_ROOT = BASE_DIR / "staticfiles"
MEDIA_URL= "media"
MEDIA_ROOT= BASE_DIR / "media"
urls.py
from django.conf import settings
from.django.conf.urls.static import static
...
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
sempre retornando /static/... /media/...
Se em uma tapa você quer que o usuário receba um HTML com várias imagens em base64, você irá deixar lento mesmo.
Tem que separar os arquivos com base64 da página, assim o usuário vai ver a página e depois carregar as imagens.
As imagens também precisam ser compactadas e leves, caso o usuário queira ver mais detalhe, que use uma lupa igual faz as grandes lojas e a imagens é carregada por completo.
Acredito que o ideal seria utilizar o S3 ou algum outro serviço parecido. Armazene no banco uma referência, como o link do S3 e envie isso para o front, vai funcionar perfeitamente.