fundo
Existem muitas imagens de alta definição no formato CDN armazenadas na Tencent Cloud, a maioria das quais no formato PNG. Como resultado, as imagens na página carregam lentamente.
Soluções front-end:
- Converter o formato png para o formato webp (compactação sem perdas)
- As imagens são carregadas sob demanda.
Os pontos a serem observados para os dois esquemas acima são os seguintes:
- Manipulação de compatibilidade do formato webp
a): Use a tag de imagem e fonte, a tag de origem pode ser definida
<picture>
<source type="MIME-TYPE" srcset="./image.webp"></source>
<img src="./image.png">
</picture>
b): Use o atributo onError da tag img: use este modo quando o formato webp não puder ser exibido
<img
src="'./image.webp"
onError={
({
currentTarget = {
} }: any) => {
currentTarget.onerror = null;
currentTarget.src = './image.png';
}}
/>
c): Use o modo js para lidar com a situação onError, que é a mesma do método anterior
const img = new Image();
img.src = './image.webp';
img.onerror = function ({
currentTarget = {
} }: any) {
currentTarget.onerror = null;
currentTarget.src = './image.png';
};
- Uma solução melhor para carregamento de imagens sob demanda
Solução 1:
De um modo geral, quando se trata de carregamento lento de imagens (carregamento sob demanda), muitas soluções online calculam a distância entre a imagem e a parte superior do navegador e comparam a altura da área visível da página + a distância de rolagem da barra de rolagem. Se for maior que, significa que a imagem não precisa ser carregada, se for menor ou igual a, significa que a imagem está prestes a ser exibida, e então a imagem precisa ser carregada.
etapas detalhadas:
const scrollTopHeight = document.documentElement.scrollTop ;
const currentClientHeight = document.documentElement.clientHeight;
const imageOffsetTop = imgs[i].offsetTop;
if(documentElement <= scrollTopHeight + currentClientHeight ) {
imgs[i].src = imgs[i].getAttribute('data-src')
}
<img data-src="image-path" />
As soluções acima para obter se img aparece na área visível são as seguintes:
element.getBoundingClientRect()
bound.top <=docment.documentElement.clientHeight
Para obter detalhes, consulte: MDN: getBoundingClintRect
No entanto, o método acima tem uma desvantagem: monitorar constantemente a rolagem da página tem um certo impacto no desempenho da página.
Assim, podemos escolher a
opção dois:
insterSetionObserver()
monitorar se o elemento aparece na área visível.
Muitos lugares dizem que esse método não é compatível, mas na verdade, de acordo com a maioria dos meus cenários, não acho que haja nenhum problema com essa compatibilidade. Você pode decidir se é aplicável de acordo com suas próprias necessidades.
etapas detalhadas:
const callback = (entires) => {
entires.forEach(item => {
if(item.isIntersecting) {
item.target.setAttribute("src", item.target.getAttribute('data-src'))
observer.unobserve(item.target)
}
})
}
const observer = new intersectionObserver(callback);
imgs.forEach(img => observer.observe(img))