Image lazy loading principle
- Whether the picture enters the viewable area
- Temporarily save the specific address of the picture to
data-src
attribute - After the picture enters the viewable area, the
img
Of the labeldata-src
Assigns the property value tosrc
attribute
IntersectionObserver
Used to observe whether elements into the viewing area, introduces the specific can see nguyen other teacher’s articles www.ruanyifeng.com/blog/2016/1…
Source github.com/KamiC6238/t…
IO /s/brave-jep…
import React, { FC, memo, useEffect, useRef } from 'react'
// CSS IN JS style
import { Container, ImageWrapper, Image } from './style'
// Use the image of type string[]
import { lazyloadImages } from './utils'
export const IntersectionObserverLazyload: FC<{}> = memo(() = > {
const observerRef = useRef(new IntersectionObserver((entries) = > {
entries.forEach((entry) = > {
const { target, intersectionRatio } = entry
// target is a specific DOM
// intersectionRatio ranges from 0 to 1, with 0 being completely invisible and 1 being completely visible
// Therefore, it only needs to judge if intersectionRatio is greater than 0
if (intersectionRatio > 0) {
const _target = target as HTMLImageElement
_target.src = _target.dataset['src']????' '
_target.onload = () = > {
_target.style.opacity = '1'
}
observerRef.current.unobserve(_target)
}
})
}))
useEffect(() = > {
Array
.from(document.getElementsByTagName('img'))
.forEach((img) = > observerRef.current.observe(img))
return () = > {
observerRef.current.disconnect()
}
}, [])
return (
<Container>
{lazyloadImages.map((image, index) => (
<ImageWrapper key={index}>
<Image
src={undefined}
data-src={image}
alt={` ${index} `}style={{ opacity: '0', transition: '.3s' }}
/>
</ImageWrapper>
))}
</Container>)})Copy the code