Método de carga diferida de imagen

Principio de carga diferida de imagen

El atributo personalizado data-src de la imagen renderizada es la ruta de la imagen real, y se juzga si la imagen está en el área no disponible. Si está en el área no disponible, el valor de la ruta de la imagen real data-src se asigna a la imagen src.

Escenario de aplicación

El escenario de la aplicación de carga diferida está sesgado hacia las solicitudes de recursos de red, lo que resuelve el problema de que el tiempo de respuesta del sitio web es demasiado largo debido a demasiadas solicitudes de recursos de red.

¿Cómo juzgar si la imagen está en el área visible?

1.offsetTop: la altura desde la parte superior del elemento actual hasta la parte superior del elemento principal

2.window.innerHeight: la altura de la ventana visible, excluyendo la barra de herramientas en la parte superior del navegador

3.scrollTop: la distancia entre la parte superior del elemento actual y la parte superior de la ventana, es decir, la altura más allá del área visible

Cuando offsetTop <= window.innerHeight + scrollTop, el elemento está en el área disponible

método uno:

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

Método dos

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

método getBoundingClientRect: Element.getBoundingClientRect() - Referencia de la interfaz API web | MDN

metodo tres

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

Tutorial de la API de IntersectionObserver: blog de Ruan Yifeng

Supongo que te gusta

Origin blog.csdn.net/qq_43307723/article/details/129087559
Recomendado
Clasificación