antecedentes
Hay muchas imágenes de alta definición en formato CDN almacenadas en Tencent Cloud, la mayoría de las cuales están en formato PNG. Como resultado, las imágenes de la página se cargan lentamente.
Soluciones frontales:
- Convertir formato png a formato webp (compresión sin pérdidas)
- Las imágenes se cargan bajo demanda.
Los puntos a tener en cuenta para los dos esquemas anteriores son los siguientes:
- Manejo de compatibilidad del formato webp
a): Use la imagen y la etiqueta de origen, se puede configurar la etiqueta de origen
<picture>
<source type="MIME-TYPE" srcset="./image.webp"></source>
<img src="./image.png">
</picture>
b): use el atributo onError de la etiqueta img: use este modo cuando no se pueda mostrar el formato webp
<img
src="'./image.webp"
onError={
({
currentTarget = {
} }: any) => {
currentTarget.onerror = null;
currentTarget.src = './image.png';
}}
/>
c): use el modo js para manejar la situación onError, que es igual que el método anterior
const img = new Image();
img.src = './image.webp';
img.onerror = function ({
currentTarget = {
} }: any) {
currentTarget.onerror = null;
currentTarget.src = './image.png';
};
- Una mejor solución para la carga de imágenes bajo demanda
Solución 1:
en términos generales, cuando se trata de la carga diferida de imágenes (carga bajo demanda), muchas soluciones en línea calculan la distancia entre la imagen y la parte superior del navegador y comparan la altura del área visible de la página + la distancia de desplazamiento de la barra de desplazamiento. Si es mayor que, significa que no es necesario cargar la imagen, si es menor o igual que, significa que la imagen está a punto de mostrarse, y luego la imagen debe cargarse.
pasos detallados:
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" />
Las soluciones anteriores para obtener si img aparece en el área visible son las siguientes:
element.getBoundingClientRect()
bound.top <=docment.documentElement.clientHeight
Para obtener más información , consulte: MDN: getBoundingClintRect
Sin embargo, el método anterior tiene un inconveniente: monitorear constantemente el desplazamiento de la página tiene cierto impacto en el rendimiento de la página.
Entonces podemos tomar la
opción dos:
insterSetionObserver()
monitorear si el elemento aparece en el área visible.
Muchos lugares dicen que este método no es compatible, pero de hecho, según la mayoría de mis escenarios, no creo que haya ningún problema con esta compatibilidad, puedes decidir si es aplicable según tus propias necesidades.
pasos detallados:
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))