记一次图片显示的处理和近期所想

180 阅读7分钟

前言

2025 开启,新的一年开启新的篇章,用信心去迎接改变!

本篇文章介绍了一次图片显示的处理过程并进行总结,在实际的业务开发中,需要更加全面的考虑问题,从整体流程上完善前端功能。

以及介绍了自己及最近所想,夹杂着我对于前端工作、职业发展的看法,希望对大家有所帮助。

图片的显示问题

问题描述

假设有一个前端页面,展示一个作品推荐列表,列表每一项包含作品信息,其中包含图片地址。类似:

{
  id: 'xx',
  image_url: 'https://image.server/path/to/image.jpg",
  other: 'xxx',
}

针对图片,我们需要考虑的:

  • 图片的大小是否影响加载速度
  • 图片是否需要懒加载
  • 图片加载失败的处理

看起来很简单,前端只需要获取服务端数据,进行列表展示就可以了。

数据缓存

因为服务端有接口请求 CD,同时服务端为了减轻服务器压力,一次返回多页的数据,所以前端需要进行数据缓存,例如一次返回 3 页的数据,第一次请求服务端接口,第二、第三次直接使用缓存数据,请求通过当前页数进行管理。

  • 根据需要进行全局状态管理。
  • 根据刷新是否需要保持状态,进行数据持久化。

显示已删除

首先服务端数据有缓存,列表数据不会及时更新。

当作品被用户删除的时候,服务端会返回空,此时前端页面需要显示“作品已删除占位图”。

<li>
  <div v-if="item.id">
    <img src="" alt="" />
  </div>
  <div v-else>
    作品已删除
  </div>
</li>

审核不通过

推荐列表展示的是审核通过的数据,也就是服务端只会返回审核通过的数据。

还是服务端数据缓存的问题,当审核通过改为不通过时,会有短期的数据问题:服务端的数据没有及时更新,审核不通过的那一条数据,仍然存在在推荐中,但其中的图片地址已不可访问,因为图片服务器上图片状态已改变。

此时需求是显示作品已删除占位图,因为如果图片加载不出来,放在那里不好看。最终这样做了。

首先这不符合实际情况,有可能给用户带来困扰,为什么自己没有删除作品,却说作品已删除?但是因为这种情况较少发生以及会更新,而且用户不那么容易刷到自己的作品,所以暂且这样处理。

后面我们会发现它带来的其他问题:

  • 图片完全不可访问:因为图片存储服务器缓存设置以及用户流量的问题,导致图片大量加载失败,于是列表数据全部显示作品已删除。
  • 审核流程问题:
    • 涉及到自动审核与人工审核。如果进行自动审核通过,再进行大量的审核不通过会导致前端显示作品已删除。
    • 或者出现大量审核通过、又开始改为审核不通过,但是审核并不是在图片服务器进行,服务器不能及时同步状态,导致大量显示作品已删除。

如何更好的显示图片状态

那么思考如何显示图片状态比较好?不应该一律显示为作品已删除,可以进行区分,例如:“作品已删除”和“作品审核中”以及“无法显示”。

服务端数据应该增加状态 status:deleted、approved、approving.

  • 审核通过:审核通过的作品设置状态 approved。
  • 审核中:审核中的作品设置状态 approving。
  • 已删除:已删除的作品设置状态 deleted,而不是返回空数据。

占位图也有几种:

  • 已删除:placeholder-deleted.jpg
  • 审核中:placeholder-approving.jpg
  • 无法显示:placeholder-error.jpg

UI 视觉上,可以对审核中的占位图进行模糊处理:

.placeholder-approving {
  filter: blur(10px);
  opacity: 0.5;
}

但是审核中的作品,实际上是审核不通过的作品,而且只是根据图片不能访问进行判断的,这样是有问题的,无法区分真正的图片加载问题。可以通过图片服务器的返回状态进行判断,例如:

图片加载失败时,可以通过 onerror 捕获,并结合请求的 HTTP 状态码来区分不同情况:

  • 404:图片资源不存在(可能已被审核不通过)。
  • 其他错误:可能是网络问题或服务器故障。
async function handleImageError(img) {
  try {
    const response = await fetch(img.src, { method: 'HEAD' });
    if (response.status === 404) {
      // 404: 图片不存在,可能是审核不通过
      img.src = 'path/to/placeholder-approving.jpg';
    } else {
      // 其他情况
      img.src = 'path/to/placeholder-error.jpg';
    }
  } catch (error) {
    // 请求失败,可能是网络问题
    img.src = 'path/to/placeholder-error.jpg';
  }
}

总结

当然,以上的所有做法不一定是最好的,也可能有未考虑到的地方。

  • 实际业务的所有边界情况都要考虑,小概率事件是否可能变成大概率事件?例如针对审核不通过的数据展示作品已删除。
  • 前端不仅仅是做数据展示,也应该关注数据来源,最好是有合适的兜底方案(完善、全面的视觉展示,良好的用户体验)。
  • 关注数据来源就要从用户量、用户行为、实际的流程上关注业务,例如推荐的数据来自哪里?Web 服务器数据如何与图片服务同步,真实的审核流程如何。

其实这里只是关于图片显示这一小小部分的思考,真实业务还有更多的问题需要考量,如果前端只是实现表面的数据展示、完成任务,就无法真正的提高解决问题的能力。编程要考虑各种边界情况,解决问题也同理。

关于我及近期所想

关于我

前端从业超过 10 年,无大厂经历,经历过跳槽、裁员,差不多各种类型的团队都待过。从自认为没有编程天赋到逐渐有所心得。普通开发一个,持续精进。

热爱写作、记录,日常记录工作遇到的问题、个人成长的所思所想。我个人经历了非常艰难的职业挣扎之路,从小白到迷茫,从兴趣与工作的矛盾、到性格与职场的冲突,从无效学习到家庭问题,回顾过往,时常遗憾,要是有一个现在这样的我引导我走过,技术是不是提高的更快?是不是更早领悟职场和工作到底是什么?

不过,我的成长更多的在于哲学观、人生观的更新完善,所以不用遗憾,正是这一点的建立,我才能改变。哲学观是很重要的,它是你一切行动的基础。

我的计划

从现在、2025 开始,我也要做出一些改变,真正尝试去帮助别人,而不是有想法又一直没有行动。我希望用自己还不那么丰富的知识和经验尽可能的帮助别人,而且不仅仅是知识,我希望用哲学观从根本上进行改变。我会从维护一个微信群、写公众号文章开始。

我也犹豫纠结很久。网上有太多的大佬,有很好的文章、教程,很多很好的内容是我写不出来的。但是我又觉得自己曾经在网上找不到答案,苦苦思索总结,也许我写的也能帮助一些人。我希望能慢慢积累,从第一步开始。

重要的是我认为一对一的对话很重要,一对一对话能够更加深入地理解个体需求和困惑,帮助对方解决具体问题,而不是泛泛而谈。欢迎关注微信公众号:前端成长指南。或者添加微信好友:zangbianxuegu 交流。