react和vue图片懒加载及实现原理

一、实现原理

  1. 核心思想

    • 只有当图片出现在视口中时,才加载图片。
    • 利用占位图或占位背景优化用户体验。
  2. 实现技术

    • 监听滚动事件:监听页面滚动,通过计算图片与视口的位置关系,判断是否需要加载图片。
    • Intersection Observer(推荐):现代浏览器提供的 API,用于检测目标元素是否进入视口,比滚动事件性能更好。
  3. 步骤

    • 设置图片的占位符(如灰色背景、默认图片)。
    • 检测图片元素是否进入视口。
    • 当图片进入视口时,将 src 属性替换为实际图片地址。

二、React 实现图片懒加载

1. 使用 Intersection Observer 实现

.

复制代码
import React, { useRef, useState, useEffect } from 'react';

const LazyImage = ({ src, alt, placeholder, className }) => {
  const [isLoaded, setIsLoaded] = useState(false);
  const imgRef = useRef();

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setIsLoaded(true);
          observer.disconnect(); // 图片加载后停止观察
        }
      },
      { threshold: 0.1 } // 10% 进入视口时触发
    );

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

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

  return (
    <img
      ref={imgRef}
      src={isLoaded ? src : placeholder}
      alt={alt}
      className={className}
    />
  );
};

export default LazyImage;
2. 第三方库
  • react-lazyload:轻量级懒加载库,支持图片、组件等。

    npm install react-lazyload

    import React from 'react';
    import LazyLoad from 'react-lazyload';

    const LazyImage = ({ src, alt, height }) => (
    <LazyLoad height={height} offset={100}>
    {alt}
    </LazyLoad>
    );

    export default LazyImage;

三、Vue 实现图片懒加载

1. 使用 Intersection Observer
复制代码
<template>
  <img
    :src="isLoaded ? src : placeholder"
    :alt="alt"
    ref="imageRef"
    class="lazy-image"
  />
</template>

<script>
export default {
  props: {
    src: String,
    placeholder: String,
    alt: String,
  },
  data() {
    return {
      isLoaded: false,
    };
  },
  mounted() {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          this.isLoaded = true;
          observer.disconnect();
        }
      },
      { threshold: 0.1 }
    );

    observer.observe(this.$refs.imageRef);
  },
};
</script>
2. 使用指令(全局注册)

懒加载在 Vue 中可通过自定义指令实现:

复制代码
// directive-lazyload.js
export const lazyload = {
  mounted(el, binding) {
    const loadImage = () => {
      const imageElement = el;
      if (imageElement) {
        imageElement.src = binding.value;
      }
    };

    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        loadImage();
        observer.disconnect();
      }
    });

    observer.observe(el);
  },
};

注册全局指令:

复制代码
import { lazyload } from './directive-lazyload';
const app = createApp(App);
app.directive('lazyload', lazyload);

使用

复制代码
<template>
  <img v-lazyload="imageSrc" alt="Lazy loaded image" />
</template>

<script>
export default {
  data() {
    return {
      imageSrc: 'https://example.com/image.jpg',
    };
  },
};
</script>
3. 第三方库
  • vue-lazyload

    npm install vue-lazyload

    import VueLazyload from 'vue-lazyload';
    app.use(VueLazyload, {
    loading: 'path/to/loading-image.png', // 占位图
    error: 'path/to/error-image.png', // 错误图
    });

    <template> Lazy loaded image </template>

四、性能优化与注意事项

  1. 减少主线程开销 :优先使用 Intersection Observer,避免滚动事件监听。
  2. 设置占位图:使用占位图片或颜色,避免加载空白区域影响体验。
  3. 图片格式优化
    • 使用 WebP 等高压缩比格式。
    • 根据设备和网络情况选择适配图片(如 srcsetpicture 标签)。
  4. 懒加载阈值 :通过设置 offsetthreshold 提前加载,提高滚动时的视觉连续性。
  5. 服务器优化 :开启图片的 lazy 属性,结合懒加载策略。

通过上述方法,React 和 Vue 都可以灵活实现高性能的图片懒加载功能。

相关推荐
前端太佬几秒前
前端对接微信扫码登录:从踩坑到填坑的全记录
前端·javascript·微信
京东零售技术9 分钟前
Taro on Harmony :助力业务高效开发纯血鸿蒙应用
前端·开源
前端大白话25 分钟前
救命!这10个Vue3技巧藏太深了!性能翻倍+摸鱼神器全揭秘
前端·javascript·vue.js
嘻嘻嘻嘻嘻嘻ys27 分钟前
《Vue 3全栈架构实战:Vite工程化、Pinia状态管理与Nuxt 3深度解析》
前端·后端
前端大白话29 分钟前
前端人必看!10个JavaScript“救命”技巧,让你告别加班改Bug
前端·javascript·程序员
cg501739 分钟前
Vue回调函数中的this
前端·javascript·vue.js
程序猿大波40 分钟前
基于Java,SpringBoot,Vue,HTML宠物相亲配对婚恋系统设计
java·vue.js·spring boot
前端太佬41 分钟前
从零到一实现扫码登录:一个前端菜鸟的踩坑实录
前端·javascript·架构
yuanmenglxb20041 小时前
微信小程序核心技术栈
前端·javascript·vue.js·笔记·微信小程序·小程序
爱编程的鱼1 小时前
如何让 HTML 文件嵌入另一个 HTML 文件:详解与实践
前端·html