MST

星途 面试题库

面试题:React图片懒加载性能优化中的资源预加载

在React的图片懒加载场景下,如何结合资源预加载技术进一步提升用户体验?说明预加载的时机、方式以及可能遇到的问题和解决方案。
34.4万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

预加载的时机

  1. 组件挂载时:在图片组件挂载到页面时,就触发预加载逻辑。例如,使用useEffect钩子在组件挂载后立即执行预加载函数。
import React, { useEffect } from 'react';

const LazyImage = ({ src }) => {
    useEffect(() => {
        const preloadImage = new Image();
        preloadImage.src = src;
    }, [src]);

    return <img src={src} alt="Lazy Loaded" />;
};

export default LazyImage;
  1. 视口临近时:结合IntersectionObserver API,当图片即将进入视口时进行预加载。这样可以确保在图片真正需要显示前提前加载,减少用户等待时间。
import React, { useRef, useEffect } from'react';

const LazyImage = ({ src }) => {
    const imgRef = useRef(null);

    useEffect(() => {
        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    const preloadImage = new Image();
                    preloadImage.src = src;
                    observer.unobserve(imgRef.current);
                }
            });
        });

        if (imgRef.current) {
            observer.observe(imgRef.current);
        }

        return () => {
            if (imgRef.current) {
                observer.unobserve(imgRef.current);
            }
        };
    }, [src]);

    return <img ref={imgRef} src={src} alt="Lazy Loaded" />;
};

export default LazyImage;

预加载的方式

  1. 使用Image对象:创建一个新的Image对象,将图片的src属性设置为要预加载的图片地址。浏览器会自动加载该图片到缓存中。
const preloadImage = new Image();
preloadImage.src = 'your-image-url.jpg';
  1. 使用fetch:通过fetch获取图片资源,然后将其存储在缓存中。这种方式更加灵活,可以处理一些自定义的缓存逻辑。
fetch('your-image-url.jpg')
  .then(response => response.blob())
  .then(blob => {
        // 可以将blob存储在缓存中,例如使用Cache API
    });

可能遇到的问题和解决方案

  1. 资源浪费:如果预加载了大量图片,但用户并没有浏览到,会造成资源浪费。
    • 解决方案:采用更加精准的预加载策略,如只预加载当前视口附近一定范围内的图片,或者根据用户的浏览习惯预测可能浏览到的图片进行预加载。
  2. 内存问题:大量图片预加载可能导致内存占用过高,特别是在移动设备上。
    • 解决方案:合理设置预加载图片的数量和频率,避免一次性预加载过多图片。同时,可以使用浏览器的缓存机制,及时释放不再使用的图片资源。
  3. 网络问题:预加载过程中可能遇到网络不稳定或图片加载失败的情况。
    • 解决方案:为预加载的图片设置加载失败的处理逻辑,例如显示一个默认的占位图片,并提供重试机制。可以使用Promise来处理预加载过程中的成功和失败情况。
const preloadImage = () => {
    return new Promise((resolve, reject) => {
        const img = new Image();
        img.onload = resolve;
        img.onerror = reject;
        img.src = 'your-image-url.jpg';
    });
};

preloadImage()
  .then(() => {
        // 预加载成功
    })
  .catch(() => {
        // 预加载失败,处理逻辑
    });