Seu carrinho está vazio no momento!
Nosso Conteúdo Incrível
Este fundo carrega de forma preguiçosa.
Leodario.com – Tudo sobre Tecnologia

Olá, pessoal! Sejam muito bem-vindos à nossa Aula 82 do curso “Loja Shopify do Zero ao Avançado”! 🚀
Se você chegou até aqui, parabéns! Isso mostra seu comprometimento em dominar o Shopify e levar suas lojas a um novo nível. Nas últimas aulas, mergulhamos fundo em diversas otimizações e personalizações que transformam uma loja comum em uma experiência de compra excepcional.
Hoje, vamos abordar um tópico crucial para a performance e a experiência do usuário: Lazy loading e Carregamento Progressivo. Prepare-se para aprender como fazer suas páginas carregarem mais rápido e de forma mais suave, encantando seus clientes e melhorando seu SEO! ✨
—
Nesta aula avançada, você irá:
sections, snippets e assets.Nas aulas anteriores, especialmente aquelas sobre performance e otimização de imagens (Aulas 78, 79 e 80), começamos a desbravar o universo de como tornar nossas lojas Shopify mais rápidas. Vimos a importância de otimizar o tamanho e o formato das imagens, usar o CDN do Shopify e até mesmo implementamos imagens responsivas.
O Lazy Loading e o Carregamento Progressivo que veremos hoje são a próxima camada dessa otimização. Eles complementam perfeitamente o que já aprendemos, garantindo que as imagens e outros elementos pesados não apenas sejam otimizados, mas também carreguem apenas quando e como forem necessários, impactando diretamente métricas como o LCP (Largest Contentful Paint) dos Core Web Vitals – algo que discutimos brevemente na Aula 77 sobre SEO Técnico. Preparados para dar mais um salto na performance? 💪
Vamos desmistificar esses termos:
1. Lazy Loading (Carregamento Preguiçoso):
2. Carregamento Progressivo (Progressive Loading):
Conceito: Vai além do Lazy Loading. Enquanto o Lazy Loading decide quando carregar, o Carregamento Progressivo define como* carregar. Ele se refere à exibição gradual ou aprimorada de um recurso. Pense naqueles efeitos em que a imagem aparece pixelizada e depois fica nítida, ou um placeholder de baixa qualidade que é substituído pela imagem final.
Existem duas formas principais de implementar Lazy Loading:
1. Lazy Loading Nativo do Navegador (loading="lazy"):
loading="lazy" na tag ![]()
ou . Os navegadores modernos cuidam do resto automaticamente.2. Lazy Loading via JavaScript (Ex: Intersection Observer API):
background-image em CSS, vídeos, ou iframes que não suportam loading="lazy" nativamente), usamos JavaScript. A Intersection Observer API é a ferramenta moderna e eficiente para isso. Ela permite que você saiba quando um elemento entra ou sai da viewport, sem a necessidade de monitorar eventos de rolagem manualmente (que podem ser caros em termos de performance).Praticamente qualquer elemento que não seja imediatamente visível na tela e que seja pesado pode se beneficiar:
que não estão no cabeçalho.Muito importante: Nunca aplique Lazy Loading em imagens ou elementos que aparecem na primeira tela do usuário (ou seja, “acima da dobra” ou “above the fold”). Estes elementos são críticos para o LCP (Largest Contentful Paint) e devem ser carregados o mais rápido possível. Adiar seu carregamento atrasaria a renderização do conteúdo principal, prejudicando a experiência e o SEO.
Dica: Use o Google PageSpeed Insights ou o Lighthouse para identificar seu LCP e garantir que ele não está sendo lazy-loaded.
Vamos colocar a mão na massa! Vou mostrar como implementar essas técnicas em um tema Shopify.
A forma mais comum e eficaz de aplicar lazy loading é nas imagens de produtos e coleções. Em um tema Shopify, as imagens geralmente são renderizadas usando o filtro img_tag do Liquid.
1. Identificando o Código da Imagem:
Navegue pelos arquivos do seu tema (em sections ou snippets). Você provavelmente encontrará algo como:
{{ product.featured_image | img_tag: product.featured_image.alt, class: 'product-image' }}
Ou, em um loop de imagens:
{% for image in product.images %}
{{ image | img_tag: image.alt, class: 'product-gallery-image' }}
{% endfor %}
2. Adicionando o Atributo loading="lazy":
O filtro img_tag aceita parâmetros adicionais, incluindo o atributo loading. Basta adicioná-lo:
{% comment %} Imagem de destaque de produto com lazy loading {% endcomment %}
{{ product.featured_image | img_tag: product.featured_image.alt, class: 'product-image', loading: 'lazy' }}
{% comment %} Imagens da galeria de produtos com lazy loading {% endcomment %}
{% for image in product.images %}
{{ image | img_tag: image.alt, class: 'product-gallery-image', loading: 'lazy' }}
{% endfor %}
Onde aplicar?
snippets/product-card.liquid: para imagens de produtos em listagens de coleção ou resultados de busca.sections/main-product.liquid: para as imagens secundárias da galeria de produtos.sections/image-with-text.liquid ou similar: para imagens que não estão no topo da página.sections/featured-collection.liquid, sections/featured-product.liquid, etc.Screenshot/Demonstração (Descrição):
product-card.liquid e a linha com img_tag antes e depois da modificação.![]()
que estão fora da viewport possuem o atributo loading="lazy". Também poderia mostrar a aba “Network” carregando as imagens sob demanda.Para elementos que não são ou com suporte nativo, ou para cenários mais controlados, usamos JS. Vamos focar em uma imagem de fundo (background image) que só deve carregar quando o elemento entra na viewport.
1. Estrutura HTML (no Liquid):
Precisamos de um placeholder e de um atributo data-src para armazenar a URL da imagem de alta resolução.
{% comment %} sections/custom-hero.liquid (exemplo de seção personalizada) {% endcomment %}
data-background-src="{{ section.settings.background_image | img_url: '1920x' }}"
style="background-image: url('{{ section.settings.background_image | img_url: '50x' | asset_url }}');">
Nosso Conteúdo Incrível
Este fundo carrega de forma preguiçosa.
{% schema %}
{
"name": "Seção com Fundo Lazy",
"settings": [
{
"type": "image_picker",
"id": "background_image",
"label": "Imagem de Fundo"
}
],
"presets": [
{
"name": "Seção com Fundo Lazy"
}
]
}
{% endschema %}
img_url: '50x' no style para ter um placeholder de baixíssima resolução.data-background-src guarda a URL da imagem de alta qualidade.2. Código JavaScript (assets/theme.js ou assets/global.js):
javascript
// assets/theme.js ou assets/global.js
document.addEventListener('DOMContentLoaded', () => {
const lazyBackgrounds = document.querySelectorAll('.lazy-background-section');
if ('IntersectionObserver' in window) {
let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyBackground = entry.target;
const imageUrl = lazyBackground.dataset.backgroundSrc;
if (imageUrl) {
lazyBackground.style.backgroundImage = url('${imageUrl}');
lazyBackground.classList.add('is-loaded'); // Adiciona classe para transição CSS, se quiser
}
lazyBackgroundObserver.unobserve(lazyBackground); // Para de observar após o carregamento
}
});
}, {
rootMargin: '0px 0px 200px 0px' // Carrega 200px antes de entrar na viewport
});
lazyBackgrounds.forEach(function(lazyBackground) {
lazyBackgroundObserver.observe(lazyBackground);
});
} else {
// Fallback para navegadores sem Intersection Observer (pode carregar tudo imediatamente ou usar polyfill)
lazyBackgrounds.forEach(function(lazyBackground) {
const imageUrl = lazyBackground.dataset.backgroundSrc;
if (imageUrl) {
lazyBackground.style.backgroundImage = url('${imageUrl}');
lazyBackground.classList.add('is-loaded');
}
});
}
});
3. Adicionando um pouco de CSS (assets/theme.css ou assets/base.css):
Para um efeito de transição suave quando a imagem final carregar.
css
/ assets/theme.css /
.lazy-background-section {
min-height: 400px; / Garante que o elemento tenha altura para ser observado /
background-size: cover;
background-position: center center;
transition: background-image 0.5s ease-in-out; / Transição para o blur-up /
filter: blur(5px); / Efeito de blur inicial para o placeholder /
transform: scale(1.02); / Pequeno zoom para disfarçar o blur /
}
.lazy-background-section.is-loaded {
filter: blur(0); / Remove o blur após o carregamento /
transform: scale(1);
}
Screenshot/Demonstração (Descrição):
.lazy-background-section com o style inicial apontando para a imagem de baixa qualidade e o data-background-src com a imagem de alta.style atualizado com a URL da imagem de alta qualidade.Vamos combinar Lazy Loading nativo com um efeito de blur-up, usando a versatilidade do Shopify para gerar diferentes tamanhos de imagem.
1. Estrutura HTML/Liquid:
Aqui, usaremos um div como contêiner, um img para o placeholder borrado, e a imagem final (com loading="lazy") que substituirá ou se sobreporá ao placeholder.
{% comment %} snippets/progressive-image.liquid {% endcomment %}
{% comment %}
Recebe um objeto de imagem Shopify e renderiza com progressive loading
Uso: {% render 'progressive-image', image_object: product.featured_image, class_name: 'product-feature-image' %}
{% endcomment %}
{% if image_object != blank %}
{% assign image_url_low_res = image_object | img_url: '50x' %}
{% assign image_url_high_res = image_object | img_url: 'master' %}
{% comment %} Você pode usar '1024x', '2048x' ou 'master' para a alta resolução {% endcomment %}
class="progressive-image-placeholder"
alt="{{ image_object.alt | escape }}"
width="50" height="{{ 50 | divided_by: image_object.aspect_ratio | round }}"
aria-hidden="true"
loading="lazy"
/>
data-srcset="
{{ image_object | img_url: '480x' }} 480w,
{{ image_object | img_url: '768x' }} 768w,
{{ image_object | img_url: '1024x' }} 1024w,
{{ image_object | img_url: '1440x' }} 1440w,
{{ image_object | img_url: '1920x' }} 1920w"
data-sizes="auto"
class="progressive-image-final"
alt="{{ image_object.alt | escape }}"
width="{{ image_object.width }}" height="{{ image_object.height }}"
loading="lazy"
/>
{% endif %}
padding-bottom truque para manter a proporção da imagem.data-src, data-srcset e data-sizes para o JavaScript e loading="lazy" para o carregamento nativo.2. Código JavaScript (assets/theme.js ou assets/global.js):
Este JS vai usar Intersection Observer para quando a imagem final deve ser carregada. Ele substitui data-src por src e data-srcset por srcset.
javascript
// assets/theme.js ou assets/global.js
document.addEventListener('DOMContentLoaded', () => {
const progressiveImages = document.querySelectorAll('.progressive-image-final');
if ('IntersectionObserver' in window) {
let imageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let img = entry.target;
img.src = img.dataset.src;
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
img.sizes = img.dataset.sizes;
}
img.classList.add('is-loaded'); // Adiciona classe para transição CSS
img.onload = () => {
// Opcional: Remover o placeholder depois que a imagem final carregou completamente
const placeholder = img.closest('.progressive-image-container').querySelector('.progressive-image-placeholder');
if (placeholder) {
placeholder.remove();
}
};
observer.unobserve(img);
}
});
}, {
rootMargin: '0px 0px 200px 0px' // Carrega 200px antes de entrar na viewport
});
progressiveImages.forEach(function(img) {
imageObserver.observe(img);
});
} else {
// Fallback: carregar todas as imagens imediatamente para navegadores sem IO
progressiveImages.forEach(function(img) {
img.src = img.dataset.src;
if (img.dataset.srcset) {
img.srcset = img.dataset.srcset;
img.sizes = img.dataset.sizes;
}
img.classList.add('is-loaded');
const placeholder = img.closest('.progressive-image-container').querySelector('.progressive-image-placeholder');
if (placeholder) {
placeholder.remove();
}
});
}
});
3. Adicionando CSS (assets/theme.css ou assets/base.css):
Para o efeito de blur e transição.
css
/ assets/theme.css /
.progressive-image-container {
position: relative;
overflow: hidden;
width: 100%;
/ padding-bottom definido via Liquid para manter proporção /
}
.progressive-image-placeholder,
.progressive-image-final {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover; / Garante que a imagem preencha o container /
}
.progressive-image-placeholder {
filter: blur(10px); / Efeito de blur no placeholder /
opacity: 1;
transition: opacity 0.5s ease-out;
}
.progressive-image-final {
opacity: 0;
transition: opacity 0.5s ease-in;
}
.progressive-image-final.is-loaded {
opacity: 1;
}
Screenshot/Demonstração (Descrição):
img.progressive-image-final recebendo src e srcset e a classe is-loaded.—
Hora de praticar!
1. Modificar um Tema Existente: Escolha um tema gratuito do Shopify (como Dawn ou Refresh).
snippets/product-card.liquid).loading="lazy") a essas imagens.2. Lazy Loading para Iframes: Se o seu tema tiver algum iframe (ex: vídeo do YouTube em uma página de produto ou seção de contato com mapa), tente aplicar Lazy Loading nele. Se o navegador suportar, basta adicionar loading="lazy". Caso contrário, pesquise uma biblioteca JS para lazy load de iframes ou adapte o código do Intersection Observer.
3. Desafio Avançado – Implementar Blur-up: Tente integrar o snippet/progressive-image.liquid e o JavaScript correspondente em uma seção de seu tema que exiba uma imagem de banner ou uma imagem de conteúdo (não a imagem principal de produto acima da dobra). O objetivo é que a imagem apareça primeiro borrada e depois nítida.
Dica: Sempre faça suas alterações em um tema duplicado ou em desenvolvimento para evitar impactar sua loja ao vivo!
—
Nesta aula super importante, você aprendeu:
loading="lazy") é a forma mais simples e eficiente para tags ![]()
e em navegadores modernos.Dominar essas técnicas é essencial para criar lojas Shopify rápidas, modernas e otimizadas para os motores de busca e, o mais importante, para seus clientes! 💖
—
Ufa! Que aula densa e prática! Demos um passo gigante na otimização de performance.
Na próxima aula (Aula 83), vamos continuar nossa jornada de otimização, mas focando em outros aspectos igualmente importantes: Otimização de Fontes e CSS Crítico. Entenderemos como carregar fontes de forma eficiente para evitar layouts instáveis (CLS) e como garantir que o CSS essencial para a primeira tela seja carregado prioritariamente, melhorando ainda mais o LCP e a velocidade percebida. Será mais uma aula prática para turbinar a sua loja!
Não perca! Até lá! 👋
img_url, img_tag etc.)