【react】react 中实现图片懒加载的解决方案

169 阅读1分钟

react-intersection-observer

react-intersection-observer

import React from 'react';
import { useInView } from 'react-intersection-observer';

const ImageLazyLoad = ({ src, alt }) => {
  const { ref, inView } = useInView({ threshold: 0.1 });
  return (
    <img
      ref={ref}
      src={inView ? src : ''}
      alt={alt}
      style={{ opacity: inView ? 1 : 0 }}
    />
  );
};

export default ImageLazyLoad;

直接使用 Intersection Observer API

import React, { useState, useEffect } from 'react';

const ImageLazyLoad = ({ src, alt }) => {
  const [isLoaded, setIsLoaded] = useState(false);
  const [imgRef, setImgRef] = useState(null);

  useEffect(() => {
    const observer = new IntersectionObserver((entries) => {
      if (entries[0].isIntersecting) {
        setIsLoaded(true);
        observer.unobserve(imgRef);
      }
    });
    if (imgRef) {
      observer.observe(imgRef);
    }
    return () => {
      if (imgRef) {
        observer.unobserve(imgRef);
      }
    };
  }, [imgRef]);

  return (
    <img
      ref={setImgRef}
      src={isLoaded ? src : ''}
      alt={alt}
      style={{ opacity: isLoaded ? 1 : 0 }}
    />
  );
};

export default ImageLazyLoad;

Next.js 里面的 Image 组件

import Image from 'next/image'
 
export default function Page() {
  return (
    <div className="grid-element">
      <Image
        priority // 设置为 ture 就是懒加载
        fill
        src="/example.png"
        sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
      />
    </div>
  )
}

本质实现的原理也是一样的,利用 Intersection Observer API

我想一些知名的开源组件也会这样优化 Image 组件。