Image lazy loading principle

  1. Whether the picture enters the viewable area
  2. Temporarily save the specific address of the picture todata-srcattribute
  3. After the picture enters the viewable area, theimgOf the labeldata-srcAssigns the property value tosrcattribute

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