Front-end image loading optimization, lazy loading, on-demand loading, webp format compatibility processing

background

There are many high-definition images in the CDN format stored in Tencent Cloud, most of which are in PNG format. As a result, the images on the page load slowly.

Front-end solutions:

  1. Convert png format to webp format (lossless compression)
  2. Images are loaded on demand.

The points to be noted for the above two schemes are as follows:

  1. Compatibility handling of webp format
    insert image description here

a): Use picture & source tag, source tag can be set

	<picture>
		<source type="MIME-TYPE" srcset="./image.webp"></source>
		<img src="./image.png">
	</picture>

b): Use the onError attribute of the img tag: use this mode when the webp format cannot be displayed

	<img
	 src="'./image.webp"
	 onError={
    
    ({
    
     currentTarget = {
    
    } }: any) => {
    
    
	   currentTarget.onerror = null;
	   currentTarget.src = './image.png';
	 }}
	/>

c): Use js mode to handle the onError situation, which is the same as the previous method

 	const img = new Image();
    img.src = './image.webp';
    img.onerror = function ({
    
     currentTarget = {
    
    } }: any) {
    
    
      currentTarget.onerror = null;
      currentTarget.src = './image.png';
    };
  1. A better solution for on-demand image loading

Solution 1:
Generally speaking, when it comes to lazy loading of images (on-demand loading), many online solutions calculate the distance between the image and the top of the browser, and compare the height of the visible area of ​​the page + the scrolling distance of the scroll bar. If it is greater than, it means that the image does not need to be loaded. If it is less than or equal to, it means that the image is about to be displayed, and then the image needs to be loaded.

detailed steps:

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" />

The above solutions to obtain whether img appears in the visible area are as follows:

element.getBoundingClientRect()
bound.top <=docment.documentElement.clientHeight

For details, please refer to: MDN: getBoundingClintRect

However, the above method has a drawback: constantly monitoring the scrolling of the page has a certain impact on the performance of the page.

So we can take
option two:
insterSetionObserver()to monitor whether the element appears in the visible area.
Many places say that this method is not compatible, but in fact, according to most of my scenarios, I don't think there is any problem with this compatibility. You can decide whether it is applicable according to your own needs.
insert image description here
detailed steps:

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))

Guess you like

Origin blog.csdn.net/xieamy/article/details/123261345