自己动手做一次图片加载优化

使用React进行说明。

背景

在前端开发中,我们经常会有在页面中展示图片的需求,抛开各式各样的懒加载插件、组件,如何自己动手将图片渲染的整个过程掌握在开发者自己手中其实可以便于我们应对需求可能的变化,以及掌握一些可能忽略掉的知识点。

场景

假设你有一个页面需要渲染一组卡片,每个卡片中都有一张图片,后端接口返回的数据为如下的对象数组:

JSON.png

问题

想象一下不做任何处理的情况下,渲染一组卡片中的图片我们可能会这样做:

显然,功能实现了,但是效果会有缺陷,在用户网络较差的情况下,用户将会在页面中看到图片一点一点的显示完整,生硬并且有卡顿感。

我们先把问题拆解一下:
图片渲染时有卡顿感、生硬

  1. 渲染时不直接展示图片
  2. 是否可以下载完成时展示Loading状态,下载完成后展示图片并增加过渡效果
  3. 多张图片如何互不影响独立进行渲染的控制
  4. 图片下载失败的错误处理和展示

为了方便思路理解,我们先不考虑图片下载失败的情况,何时渲染Loading状态还是图片本身其实取决于每张图片下载是否完成,不论是下载成功或者是下载失败。这个状态字段我们先暂定为isDownloadActionDone,该字段不是1对n的关系,而是每张图片一一对应自己的isDownloadActionDone字段,避免对其他图片产生影响,所以先对后端返回的数据进行一点处理:

接下来,我们可以对每张图片进行预下载,考虑到React本身对这种状态变动会进行合并,利用递归串行的控制每张图片的下载,并修改对象数组中对应的项的isDownloadActionDone字段为true,需要注意的是无论图片下载成功与否,我们只关心这个下载动作是否完成,我们就可以在render函数中循环渲染卡片并利用该字段区分何时渲染Loading加载中的组件或者图片本身:

此时的效果是列表渲染时会在卡片中先出现Loading,每张图片下载动作结束后会出现图片本身,虽然没有卡顿感,但是效果是非常生硬的,我们可以加上一些CSS使得图片出现时带有过渡效果。

目前我们基本完成了需求,图片资源将进行串行加载、下载失败的图片不会堵塞其他图片的下载、下载中的图片会先展示Loading、下载完成将过渡的加载图片。

完善

  • 如果图片下载失败,将会展示我们设置好的图片alt属性值并有一个图片缺失的icon,如果我们想要在图片下载不成功的情况下展示一个自定义的暂无缩略图该怎么办呢?

思路

我们在handleDownImg方法中,针对下载成功与失败的两个钩子函数的内容是一样的,只需要增加一个每个图片的errFlag下载失败字段处理即可,下载失败的则置为true

而render中的展示逻辑也需要进行一些修改:

最终效果(Slow 3G下的效果,加载会有点慢):

总结

遇到需求花时间找各种现成的组件不如静下心来尝试一下自己去实现,共勉。

作者: github.com/fatdoge

tag(s): 技术
show comments · back · home
Edit with markdown