欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React實現(xiàn)圖片懶加載的常見方式

 更新時間:2024年01月09日 08:23:49   作者:Mh  
圖片懶加載是一種優(yōu)化網(wǎng)頁性能的技術(shù),它允許在用戶滾動到圖片位置之前延遲加載圖片,通過懶加載,可以在用戶需要查看圖片時才加載圖片,避免了不必要的圖片加載,本文給大家介紹了React實現(xiàn)圖片懶加載的常見方式,需要的朋友可以參考下

前言

圖片懶加載是一種優(yōu)化網(wǎng)頁性能的技術(shù),它允許在用戶滾動到圖片位置之前延遲加載圖片。通過懶加載,可以在用戶需要查看圖片時才加載圖片,避免了不必要的圖片加載,從而提高了網(wǎng)頁的加載速度和用戶體驗。

方案一

實現(xiàn)思路

在說明思路之前,先了解幾個常見的視圖屬性。

  • clientHeight:可視區(qū)域的高度,對應(yīng)的也就是下圖中的滾動區(qū)域。
  • scrollTop:滾動條滾動的高度,它指的是內(nèi)容區(qū)的頂部到可視區(qū)域頂部的距離。
  • offsetTop:元素到offsetParent頂部的距離。
  • offsetParent:距離元素最近的一個具有定位的祖宗元素(relative,absolute,fixed),若祖宗都不符合條件,offsetParent為body。

圖解:

根據(jù)上面的圖解可知,當(dāng)圖片的滾動條滾動的高度加上可視區(qū)域的高度大于當(dāng)前的圖片的offsetTop,那么說明圖片正在進入可視區(qū)域。這個時候便可以加載當(dāng)前圖片。

第一步

模擬后臺返回的圖片url,遍歷產(chǎn)生一個url集合,用于后面的懶加載使用。

const imgUrls = (num = 10) => {
  const urls = [];
  for (let i = 0; i < num; i++) {
    const url = `https://robohash.org/${i}.png`;
    urls.push(url);
  }
  return urls;
};

第二步

遍歷圖片url集合,渲染100張loading圖片,css部分省略。

    <div className={styles['box-one']} ref={scrollRef}>
      {imgUrls(100).map((item) => {
        return <img data-src={item} key={item} src={loadingUrl} alt="" />;
      })}
    </div>

效果預(yù)覽

第三步

監(jiān)聽容器的滾動事件,當(dāng)容器滾動時計算容器的高度加上滾動條的高度大于當(dāng)前圖片的offsetTop時加載當(dāng)前的圖片。完整代碼如下:

import loadingUrl from '@/assets/imgs/loading.jpg';
import { useEffect, useRef } from 'react';
import styles from '../index.less';

// 圖片url
const imgUrls = (num = 10) => {
  const urls = [];
  for (let i = 0; i < num; i++) {
    const url = `https://robohash.org/${i}.png`;
    urls.push(url);
  }
  return urls;
};

const LazyLoading = () => {
  const scrollRef = useRef({} as any);

  // 滾動事件
  const changeScroll = () => {
    const clientHeight = scrollRef?.current.clientHeight; //可視區(qū)域高度
    const scrollTop = scrollRef?.current.scrollTop; //滾動條滾動高度
    const childNodes = scrollRef?.current.childNodes; // 獲取所有圖片集合

    for (let j = 0; j < childNodes.length; j++) {
      const element = childNodes[j];
      if (scrollTop + clientHeight > element.offsetTop) {
        element.src = element.getAttribute('data-src'); // 替換當(dāng)前的src
      }
    }
  };

  useEffect(() => {
    changeScroll(); // 第一次渲染的時候替換loading圖片
  }, []);

  return (
    <div className={styles['box-one']} ref={scrollRef} onScroll={changeScroll}>
      {imgUrls(100).map((item) => {
        return <img data-src={item} key={item} src={loadingUrl} alt="" />;
      })}
    </div>
  );
};

export default LazyLoading;

效果預(yù)覽

方案二

實現(xiàn)思路

方案二的實現(xiàn)思路利用瀏覽器提供的 IntersectionObserver API實現(xiàn)。IntersectionObserver API提供了一種方便的方式來監(jiān)視目標(biāo)元素和其祖先元素或視窗之間的交叉狀態(tài)變化。當(dāng)目標(biāo)元素進入或離開視口時,可以觸發(fā)回調(diào)函數(shù),進行相應(yīng)的操作。它的原理是通過注冊一個回調(diào)函數(shù)來觀察特定元素的交叉狀態(tài)變化,并在滿足條件時執(zhí)行相應(yīng)的操作。

使用 IntersectionObserver API非常簡單,可以通過創(chuàng)建一個 IntersectionObserver 實例,并傳入回調(diào)函數(shù)和選項對象來實現(xiàn)。回調(diào)函數(shù)會在目標(biāo)元素的交叉狀態(tài)發(fā)生變化時被調(diào)用,并接收一個參數(shù),包含有關(guān)交叉狀態(tài)的信息。

實現(xiàn)完整代碼

import loadingUrl from '@/assets/imgs/loading.jpg';
import styles from '../index.less';
import React, { useRef, useEffect, useState } from 'react';
// 圖片url
const imgUrls = (num = 10) => {
  const urls = [];
  for (let i = 0; i < num; i++) {
    const url = `https://robohash.org/${i}.png`;
    urls.push(url);
  }
  return urls;
};

const LazyLoadImage = ({ src, alt }) => {
  const [imageSrc, setImageSrc] = useState(loadingUrl);
  const imgRef = useRef(null as any);

  useEffect(() => {
    let observer: IntersectionObserver;
    if (imgRef.current) {
      // 創(chuàng)建IntersectionObserver實例
      observer = new IntersectionObserver(
        ([entry]) => {
          // 當(dāng)圖片進入可視區(qū)域時,設(shè)置圖片地址進行加載
          if (entry.isIntersecting) {
            setImageSrc(src);
            observer.unobserve(imgRef.current);
          }
        },
        {
          rootMargin: '0px 0px 200px 0px', // 可視區(qū)域的上邊距設(shè)置為200px
        },
      );
      observer.observe(imgRef.current); //開始觀察目標(biāo)元素
    }
    return () => {
      if (observer && observer.unobserve) {
        observer.unobserve(imgRef.current);
      }
    };
  }, [src]);

  return <img ref={imgRef} src={imageSrc} alt={alt} />;
};

const LazyLoading = () => {
  return (
    <div className={styles['box-two']}>
      {imgUrls(100).map((item) => {
        return <LazyLoadImage src={item} alt="lazy load image" />;
      })}
    </div>
  );
};

export default LazyLoading;

實現(xiàn)效果

注意事項

在初始化的時候,需要給imageSrc設(shè)置一個初始化的loading地址,如果沒有的話,初始化的時候會加載多張圖片。

方案三

實現(xiàn)思路

利用react的懶加載庫react-lazyload,在使用之前需要先安裝 yarn add react-lazyload,這里介紹幾個它的常見屬性:

  • scrollContainer: 指定的滾動的區(qū)域,默認值是undefined,如果沒有指定默認是窗口的視圖作為滾動區(qū)域。
  • offset: 元素距離視口頂部的距離,當(dāng)達到這個距離時,元素將被加載。
  • scroll: 是否監(jiān)聽滾動
  • height: 渲染元素的占位符的高度。
  • overflow : 如果溢出容器,延遲加載組件

代碼實現(xiàn)

因為這里實現(xiàn)的圖片懶加載是局部懶加載,所以需要指定 scrollContainer,scrollContainer 的值DOM對象。在實現(xiàn)的過程中,同時需要設(shè)置overflow為true,以及height的值。

import react, { useRef, useEffect } from 'react';
import LazyLoad from 'react-lazyload';
import styles from '../index.less';

// 圖片url
const imgUrls = (num = 10) => {
  const urls = [];
  for (let i = 0; i < num; i++) {
    const url = `https://robohash.org/${i}.png`;
    urls.push(url);
  }
  return urls;
};

const LazyLoading = () => {
  const scrollRef = useRef({} as any);

  return (
    <div className={styles['box-three']} ref={scrollRef}>
      {imgUrls(100).map((item) => {
        return (
          <LazyLoad
            height={200}
            overflow={true}
            offset={0}
            key={item}
            scroll={true}
            scrollContainer={scrollRef.current} // DOM
          >
            <img src={item} alt="" />
          </LazyLoad>
        );
      })}
    </div>
  );
};

export default LazyLoading;

實現(xiàn)效果

以上就是React實現(xiàn)圖片懶加載的常見方式的詳細內(nèi)容,更多關(guān)于React圖片懶加載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 插件化機制優(yōu)雅封裝你的hook請求使用方式

    插件化機制優(yōu)雅封裝你的hook請求使用方式

    這篇文章主要為大家介紹了插件化機制優(yōu)雅封裝你的hook請求使用方式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • 簡化Cocos和Native交互利器詳解

    簡化Cocos和Native交互利器詳解

    這篇文章主要為大家介紹了簡化Cocos和Native交互利器詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • React實現(xiàn)虛擬滾動的三種思路詳解

    React實現(xiàn)虛擬滾動的三種思路詳解

    在??web??開發(fā)的過程中,或多或少都會遇到大列表渲染的場景,為了解決大列表造成的渲染壓力,便出現(xiàn)了虛擬滾動技術(shù),本文主要介紹虛擬滾動的三種思路,希望對大家有所幫助
    2024-04-04
  • react-redux及redux狀態(tài)管理工具使用詳解

    react-redux及redux狀態(tài)管理工具使用詳解

    Redux是為javascript應(yīng)用程序提供一個狀態(tài)管理工具集中的管理react中多個組件的狀態(tài)redux是專門作狀態(tài)管理的js庫(不是react插件庫可以用在其他js框架中例如vue,但是基本用在react中),這篇文章主要介紹了react-redux及redux狀態(tài)管理工具使用詳解,需要的朋友可以參考下
    2023-01-01
  • ReactNative頁面跳轉(zhuǎn)Navigator實現(xiàn)的示例代碼

    ReactNative頁面跳轉(zhuǎn)Navigator實現(xiàn)的示例代碼

    本篇文章主要介紹了ReactNative頁面跳轉(zhuǎn)Navigator實現(xiàn)的示例代碼,具有一定的參考價值,有興趣的可以了解一下
    2017-08-08
  • React使用Context與router實現(xiàn)權(quán)限路由詳細介紹

    React使用Context與router實現(xiàn)權(quán)限路由詳細介紹

    這篇文章主要介紹了React使用Context與router實現(xiàn)權(quán)限路由的詳細過程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-01-01
  • React工作流程及Error Boundaries實現(xiàn)過程講解

    React工作流程及Error Boundaries實現(xiàn)過程講解

    這篇文章主要介紹了React工作流程及Error Boundaries實現(xiàn)過程講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-02-02
  • React組件通信淺析

    React組件通信淺析

    這篇文章主要介紹了React組件通信,在開發(fā)中組件通信是React中的一個重要的知識點,本文通過實例代碼給大家講解react中常用的父子、跨組件通信的方法,需要的朋友可以參考下
    2022-12-12
  • React Native中的RefreshContorl下拉刷新使用

    React Native中的RefreshContorl下拉刷新使用

    本篇文章主要介紹了React Native中的RefreshContorl下拉刷新使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • React觸發(fā)render的實現(xiàn)方法

    React觸發(fā)render的實現(xiàn)方法

    這篇文章主要介紹了React觸發(fā)render的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評論