实战:使用 React 实现渐进式加载图片

简介: 图片对网站有很大的影响。它们的存在改善了用户体验,提高了用户粘性。然而,加载高质量的图片需要时间,而且会让这种体验更令人沮丧,尤其是在网速较慢的情况下。为了解决这个问题,开发人员需要部署支持积极加载体验的策略。其中一个策略是渐进式图像加载。

图片对网站有很大的影响。它们的存在改善了用户体验,提高了用户粘性。然而,加载高质量的图片需要时间,而且会让这种体验更令人沮丧,尤其是在网速较慢的情况下。

为了解决这个问题,开发人员需要部署支持积极加载体验的策略。其中一个策略是渐进式图像加载。

在本文中,我们将学习渐进式图像加载,如何在React中实现这个策略。我将从以下几个步骤介绍:

  1. 为什么渐进式图像加载是有用的
  2. React中的渐进式图像加载技术

    • 创建一个图像组件
    • 将缩略图更新为实际图像
    • 实现过渡模糊
    • 使用库逐步加载图像

为什么渐进式图像加载是有用的

使用渐进式图像加载,开发人员可以显示低分辨率的图像或预览图像,直到实际的图像加载。这通过提供图像随时出现的感知来改善用户体验。

下面的GIF演示了如何使用本地元素<img />来渲染图像。

gif
正如我们所看到的,尽管页面已经加载,但图像在呈现之前需要多花一秒钟的时间,从而导致空白。当我们的网络连接速度非常慢时,这种体验就会恶化。

通过使用渐进式加载技术,我们可以渲染图像的小文件大小版本,以减少加载时间。一旦加载了高分辨率版本,我们就可以交换图像文件了。请看下面的GIF演示:
gif
由于占位符图像几乎是立即加载的,这种策略也可以帮助减少由网页图像引起的布局变化问题。请注意,出现布局变化主要是因为浏览器不知道要为图像保留多少空间。

我们可以通过添加图像的宽度和高度属性来防止这种行为。这将通知浏览器为图像预留一定数量的空间。然后我们必须对CSS文件中的图像应用max-width: 100%和height: auto,以确保图像在响应式布局中的正确行为。

在本文中,我们将学习如何改进用户体验,并通过在React中从无到有地加载图像来防止布局变化。我们还将学习如何使用外部库来实现相同的结果。

React 中的渐进式图像加载技术

渐进式图像的魔力是通过创建两个图像版本实现的:即实际图像和较小的文件版本(通常小于2kB)。

低质量的图像首先被加载以快速显示,然后在主图像下载时被放大以适应主图像的宽度。然后,一个模糊过滤器和适当的CSS过渡应用。

GatsbyNext.js这样的React框架也在它们的图像组件中使用了这种模式。但是,框架不是让用户手工创建一个小版本的图像,而是从源图像自动生成它。

此外,这些框架使用高级的图像处理选项,并允许延迟加载屏幕下方的图像。

在我们的例子中,焦点是使用React实现渐进图像加载。让我们开始实现它。

创建一个图像组件

我们将创建一个名为ProgressiveImg的图像组件,以封装<img />元素和用于渐进加载的逻辑。然后可以使用该组件替换本地<img />元素。

const ProgressiveImg = ({ placeholderSrc, src, ...props }) => {
  return (
    <img
      {...{ src: placeholderSrc, ...props }}
      alt={props.alt || ""}
      className="image"
    />
  );
};
export default ProgressiveImg;

在上面的代码中,组件接收实际的图像源src、它的占位符源placeholderSrc和我们传递的其他所有props然后,我们将这些props分配给<img />元素属性。

注意我们是如何使用扩展操作符来注入组件接收到的任何其他props的。例如,我们将在稍后看到,组件将接收所需的图像宽度和高度。与此同时,我们为src分配了一个占位符图像源,以便快速显示。

接下来,让我们确保将上述所有props传递给<ProgressiveImg />,就像这样:

import ProgressiveImg from "./components/ProgressiveImg";
import image from "./images/large_.jpg";
import placeholderSrc from "./images/tiny_.jpg";

export default function App() {
  return (
    // ...
    <ProgressiveImg
      src={image}
      placeholderSrc={placeholderSrc}
      width="700"
      height="465"
    />
    // ...
  );
}

正如在代码中所看到的,我们传递了图像及其小尺寸版本,并将其调整为小于2kB。我们还必须沿着图像的宽度和高度传递,以防止布局偏移。

如果图像大小大于指定的值,请确保保持长宽比。这样,前端应该看起来像这样:
img

将缩略图更新为实际图像

为了更新imgsrc并呈现实际的图像,我们必须通过useState Hook默认的图像源存储在一个状态变量中。然后,我们可以在实际图片加载后更新useEffect Hook中的变量。如下所示:

import { useState, useEffect } from "react";

const ProgressiveImg = ({ placeholderSrc, src, ...props }) => {
  const [imgSrc, setImgSrc] = useState(placeholderSrc || src);

  useEffect(() => {
    // update the image
  }, []);

  return (
    <img
      {...{ src: imgSrc, ...props }}
      alt={props.alt || ""}
      className="image"
    />
  );
};
export default ProgressiveImg;

注意,imgsrc属性现在被分配了一个状态变量的值。默认情况下,如果我们有占位符,这个值会被设置为它。否则,它将被分配主图像。

接下来,让我们更新useEffect钩子:

useEffect(() => {
  const img = new Image();
  img.src = src;
  img.onload = () => {
    setImgSrc(src);
  };
}, [src]);

在这个Hook中,我们首先创建一个img元素,方法是实例化一个Image()对象并将src属性设置为实际的图像源。

使用图像对象的onload事件处理程序,我们可以检测实际的图像何时在后台完全加载。然后,我们将图像src更新为实际的图像。
gif3

实现过渡模糊

让我们添加一个CSS过渡模糊平滑的效果。在ProgressiveImg组件中,在return语句的上方添加以下代码:

const customClass =
    placeholderSrc && imgSrc === placeholderSrc ? "loading" : "loaded";

我们将根据加载状态动态地向图像添加类名

因此,更新<img />以包含自定义类名:

return (
  <img
    // ...
    className={`image ${customClass}`}
  />
);

如果实际图像仍在加载中,则向图像添加一个loading。否则,我们添加一个loaded类。我们更新CSS,使其包含样式规则:

.loading {
  filter: blur(10px);
  clip-path: inset(0);
}
.loaded {
  filter: blur(0px);
  transition: filter 0.5s linear;
}

使用第三方库实现

我们还可以通过使用一个名为react-progressive-graceful-image的库来实现渐进式加载图像。要使用它,我们必须安装它:

npm i react-progressive-graceful-image

然后我们可以导入progresveimage组件,并像这样实现它:

import ProgressiveImage from "react-progressive-graceful-image";
import image from "./images/large_.jpg";
import placeholderSrc from "./images/tiny.jpg";

export default function App() {
  return (
    // ...
    <ProgressiveImage src={image} placeholder={placeholderSrc}>
      {(src, loading) => (
        <img
          className={`image${loading ? " loading" : " loaded"}`}
          src={src}
          alt="sea beach"
          width="700"
          height="465"
        />
      )}
    </ProgressiveImage>
    // ...
  );
}

progresveimage组件使用props来实现渐进式图像加载。在它的子函数prop中,我们可以在渲染回调函数中访问srcloading参数。

通过loading参数,我们可以动态地向img元素添加类。当实际图像加载时,loading返回true;否则,返回false。

结尾

通过实现渐进式图像加载技术,我们可以极大地改善React项目中的用户体验。

在本文中,我们介绍了如何在React中加载有外部库和没有外部库的图像。我希望你已经学到了很多,并且喜欢这篇文章。

相关文章
|
4月前
|
编解码 前端开发 开发者
React 图片组件样式自定义:常见问题与解决方案
在 React 开发中,图片组件的样式自定义常因细节问题导致布局错乱、性能损耗或交互异常。本文系统梳理常见问题及解决方案,涵盖基础样式应用、响应式设计、加载状态与性能优化等,结合代码案例帮助开发者高效实现图片组件的样式控制。重点解决图片尺寸不匹配、边框阴影不一致、移动端显示模糊、加载失败处理及懒加载等问题,并总结易错点和最佳实践,助力开发者提升开发效率和用户体验。
138 22
|
4月前
|
前端开发 数据可视化 测试技术
React音频播放列表组件开发实战:常见问题与避坑指南
本文介绍了构建React音频播放列表组件的核心架构与常见问题解决方案。通过管理播放状态、列表索引和音频进度,结合异步控制、状态清理、节流优化等技术,确保流畅的用户体验。针对移动端兼容性、内存泄漏、列表渲染性能等问题提供了具体修复方案,并分享了自定义Hook封装、可视化音频波形等进阶实践。最后,总结了性能优化法则和测试关键点,帮助开发者打造生产级可靠的音频播放组件。
134 18
|
6月前
|
前端开发 UED 索引
React 图片灯箱组件 Image Lightbox
图片灯箱组件是一种常见的Web交互模式,用户点击缩略图后弹出全屏窗口展示大图,并提供导航功能。本文介绍了基于React框架的图片灯箱组件开发,涵盖初始化状态管理、图片加载与预加载、键盘和鼠标事件处理等常见问题及解决方案。通过`useState`和`useEffect`钩子管理状态,使用懒加载和预加载优化性能,确保流畅的用户体验。代码案例展示了组件的基本功能实现,包括打开/关闭灯箱、切换图片及键盘操作。
230 80
|
8月前
|
前端开发 JavaScript API
React Native实战:构建跨平台移动应用
React Native实战:构建跨平台移动应用
120 0
|
8月前
|
前端开发 API UED
React 懒加载图片 Lazy Image
懒加载是一种优化技术,通过延迟加载不在视口内的图片,减少初始页面加载时间,提升用户体验。本文从基础概念入手,逐步探讨 React 中实现图片懒加载的常见问题、易错点及解决方案,并通过代码案例详细解释。
279 3
|
8月前
|
移动开发 前端开发 JavaScript
React 表单验证实战
【10月更文挑战第25天】本文介绍了 React 表单验证的常见方法,包括原生 HTML5 验证、自定义验证逻辑和第三方库(如 Formik 和 Yup)的使用。通过具体代码示例,详细讲解了每种方法的实现步骤,并探讨了常见问题和易错点及其解决方法。旨在帮助开发者提高表单验证的有效性和安全性。
189 8
|
9月前
|
前端开发 数据安全/隐私保护
前端技术实战:React Hooks 实现表单验证
【10月更文挑战第1天】前端技术实战:React Hooks 实现表单验证
|
10月前
|
前端开发
React技术栈-react使用的Ajax请求库实战案例
这篇文章介绍了在React应用中使用Axios和Fetch库进行Ajax请求的实战案例,展示了如何通过这些库发送GET和POST请求,并处理响应和错误。
110 10
React技术栈-react使用的Ajax请求库实战案例
|
11月前
|
前端开发 Java UED
JSF 面向组件开发究竟藏着何种奥秘?带你探寻可复用 UI 组件设计的神秘之路
【8月更文挑战第31天】在现代软件开发中,高效与可维护性至关重要。JavaServer Faces(JSF)框架通过其面向组件的开发模式,提供了构建复杂用户界面的强大工具,特别适用于设计可复用的 UI 组件。通过合理设计组件的功能与外观,可以显著提高开发效率并降低维护成本。本文以一个具体的 `MessageComponent` 示例展示了如何创建可复用的 JSF 组件,并介绍了如何在 JSF 页面中使用这些组件。结合其他技术如 PrimeFaces 和 Bootstrap,可以进一步丰富组件库,提升用户体验。
115 0
|
11月前
|
开发者
告别繁琐代码,JSF标签库带你走进高效开发的新时代!
【8月更文挑战第31天】JSF(JavaServer Faces)标准标签库为页面开发提供了大量组件标签,如`&lt;h:inputText&gt;`、`&lt;h:dataTable&gt;`等,简化代码、提升效率并确保稳定性。本文通过示例展示如何使用这些标签实现常见功能,如创建登录表单和展示数据列表,帮助开发者更高效地进行Web应用开发。
104 0