Image lazy loading method

Image lazy loading principle

The custom attribute data-src of the rendered img is the real image path, and it is judged whether the image is in the unavailable area. If it is in the unavailable area, the value of the real image path data-src is assigned to the image src.

Application Scenario

The application scenario of lazy loading is biased towards network resource requests, which solves the problem that the website response time is too long caused by too many network resource requests.

How to judge whether the picture is in the viewable area?

1.offsetTop: the height from the top of the current element to the top of the parent element

2.window.innerHeight: The height of the visible window, excluding the toolbar at the top of the browser

3.scrollTop: the distance between the top of the current element and the top of the window, that is, the height beyond the visible area

When offsetTop <= window.innerHeight + scrollTop, the element is in the available area

method one:

function App() {
  const [imgList, setImgList] = useState([])
  const [start, setStart] = useState(0)
  const [end, setEnd] = useState(10)

  useEffect(() => {
    let list:any = []
    for (let index = 0; index < 10000; index++) {
      list.push('/vite.svg')
    }
    setImgList(list)
  },[])
  
  const handleScroll = () => {
    let img = document.getElementsByTagName('img')
    const viewHeight = window.innerHeight
    const scrollTop = document.querySelector('.App')?.scrollTop
    const maxViewHeight = viewHeight + scrollTop
    let n = 11
    for (let i = n; i < img.length; i++) {
      if(img[i].offsetTop <=  maxViewHeight){
        const src = img[i].getAttribute('data-src')
        img[i].src = src || ''
      }
      n = i+1
    }
  }

  return (
    <div className="App" onScroll = {handleScroll}>
      <div className='box'>
        {imgList.map((item,index) => {
          if(index >= start && index <= end){
            return <img src={item} data-src="" className="logo" alt="Vite logo" key={index}/>
          } else {
            return <img src="" data-src={item} className="logo" alt="Vite logo" key={index}/>
          }
        })}
      </div>
    </div>
  )
}

Method Two

 const handleScroll = () => {
    let img = document.getElementsByTagName('img')
    const viewHeight = document.querySelector('.App')?.clientHeight
    let n = 11
    for (let i = n; i < img.length; i++) {
      
      if(img[i].getBoundingClientRect().top <=  viewHeight){
        const src = img[i].getAttribute('data-src')
        img[i].src = src || ''
      }
      n = i+1
    }
  }

getBoundingClientRect method: Element.getBoundingClientRect() - Web API interface reference | MDN

Method Three

import { useState, useEffect, } from 'react'
import reactLogo from './assets/react.svg'
import './App.css'

function App() {
  const [imgList, setImgList] = useState( [])

  useEffect(() => {
    let list:any = []
    for (let index = 0; index < 10000; index++) {
      list.push('/vite.svg')
    }
    setImgList(list)
  },[])
  
  useEffect(() => {
    if(IntersectionObserver){
      imgList.length && lazyLoad()
    }
  },[imgList])

  const lazyLoad = () => {
    let img = document.getElementsByTagName('img')

    let io = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        // 获取当前元素
        let curImg = entry.target
        console.log(entry);
        // 判断是否已经处于可视区域
        if (entry.intersectionRatio > 0 && entry.intersectionRatio <= 1) {
          curImg.setAttribute('src', curImg.getAttribute('data-src'))
        }
      })
    })

    Array.from(img).forEach((element) => {
      io.observe(element)
    })
  }

  return (
    <div className="App" onScroll = {handleScroll}>
      <div className='box'>
        {imgList.map((item,index) => {
           return <img src="" data-src={item} className="logo" alt="Vite logo" key={index}/>
        })}
      </div>
    </div>
  )
}

export default App

IntersectionObserver API tutorial - Ruan Yifeng's weblog

Guess you like

Origin blog.csdn.net/qq_43307723/article/details/129087559