图片渐进式加载(progressive)的一次浅尝辄止的探索

2021-11-29 14:03:11 +08:00
 devwolf
以下仅我盲人摸象式的总结,主要是希望 v 佬们实时指出修正。

没有涉及到底层代码的探索,主管提到不用我们重复造轮子,没去仔细研究,但光是“除去底层外如何实现”这点概念就折磨了好一会儿(一天半)。


首先,我刚接到产品提到的这个需求时,自己的脑回路是——我应该去搜索“图片懒加载、图片模糊加载”这些关键字,但是(百度)很歪,这些关键字的结果没有给我提供太多我能用的信息。

一则“medium.com 是如何让图片加载时从模糊到清晰的?”的知乎吸引到了我注意力,https://www.zhihu.com/question/40757342
其中,“不需要加载双图片”的那楼提到了“递增式编码( Progressive Encoding )”这个概念。
我之所以关注这楼,因为周五的时候询问了后端,"当时的询问"没问到图片处理参数,导致我一度放弃了找后台提供一份模糊版的图片。

Progressive 这个词,让我在 github 上收货颇丰。因为项目需要 d.ts ,最终选择了 react-progressive-image-loading 这个插件。也因为第一眼我能找到 transitionTime 这样的参数,以及给 img 添加其他属性的入口。
https://github.com/wcandillon/react-progressive-image-loading
“缺点”嘛,两边会有白色光边,这个是找产品妥协了。

但是,
但是这个组件并不能给我提供另一份模糊版的图。
我隔离归来的一位同事给我提供了思路,他以前写图片组件的时候有听主管介绍过,前端可以通过
src={`${item.url}?op=thumb/fit/w/323/h/181`}这样的参数拿到指定尺寸的图片。
与 antd4.x 官方 Image 里一例用阿里云 oss 的不谋而合,那例 url 的"serach"参数长这样
?x-oss-process=image/blur,r_50,s_50/quality,q_1/resize,m_mfit,h_200,w_200

在我琢磨"渐进加载"的期间,他又试错出了 q 这个 quality 参数,虽然没用上:(
最终,我把处理参数里的宽高都除以了二十四,然后用 css 扩回正常大小,这样就拿到了模糊图片。

```
<ProgressiveImage
transitionTime={1800}
preview={`${xxx.cover_url}?op=thumb/fit/w/${xxx/24}/h/${xxx/24}`}
src={`${xxx.cover_url}?op=thumb/fit/w/${xxx}/h/${xxx)}`}
render={(src, style) => <img
src={src}
className={styles["vso-waterfall-cover"]}
alt={item.case_title}
style={Object.assign(style, {
width: xxx,
height: xxx
})} />}
/>
```

最后,好奇和存疑的点还在那个“图片处理参数”上,似乎是对象存储、cdn 提供的,接手的后端也不清楚可以这么使用。

这次能即时解决这个需求,感觉运气占了很大比例 orz
上周在“能不能只靠前端实现”这个环节调研了好久,
结果上而言确实不用后端同事协助……那个图片处理似乎是别处提供的
1568 次点击
所在节点    前端开发
12 条回复
murmur
2021-11-29 14:09:09 +08:00
那种所谓渐进式加载好像是 png 的格式决定的,有两种,一种是从完整到不完整,一种是从糊到清晰

如果是加载 2 个图,我认为是浪费,反正最后都要加载图片,要么懒加载,要么骨架占位,何必还弄不清晰的图片
devwolf
2021-11-29 14:22:23 +08:00
@murmur 产品那边想要自家落地页还原出 https://unsplash.com/
这样的效果,我便只能想到塞个模糊版了。

图片编码那块还没细究,是指图片上传前,统一处理成指定格式后,便能默认的从糊到清晰展示了吗?
我再查查看
murmur
2021-11-29 14:25:41 +08:00
@devwolf 我不知道你是说的哪个页面,他们的列表页本身就是几十 kb 的缩略图,完全不存在什么过度加载

这种肯定是点击才加载大图

唯一的设计,看他们好像内置了多种缩略图格式,应对不同的屏幕大小,然后用各种计算去选一个适合的

但是本质上还是大小图懒加载
sdqhzhm
2021-11-29 14:29:01 +08:00
progressive JPEG 看下
cairnechen
2021-11-29 14:30:30 +08:00
你说的是往下滚动时候那个一闪而过的模糊状态?
bnm965321
2021-11-29 14:31:18 +08:00
nextjs/Image 好像都做好了
yuzo555
2021-11-29 14:34:39 +08:00
不知道你需要实现的具体效果是什么,如果是一般网页,可以先加上 loading="lazy",这样在图片出现在屏幕上时才会进行加载;其次就是图片本身需要 progressive ,这个是图片本身决定的,效果是先加载模糊的图像显示出来,然后再开始加载完整的版本,这样网络差的用户一开始也可以看个大概。
对象存储 /CDN 基本上都支持这个参数的。
devwolf
2021-11-29 14:50:24 +08:00
@cairnechen 嗯。产品那边后来补充,即使图片已经加载完成可看,也必须得有这种模糊渐进效果。

@yuzo555 对,就是这个参数。之前压根不知道有这么回事,就白忙活儿了好久😂,问上面上面也不知道……
“图片本身需要 progressive”,应该是这样的要求了
oott123
2021-11-29 15:07:20 +08:00
方向错啦
参考: https://blurha.sh/
devwolf
2021-11-29 15:25:36 +08:00
@oott123 感谢提供新思路。
blurhash 这个惊艳的插件,我也顺着找到了它的 react 版
https://github.com/woltapp/react-blurhash

粗看了一下,感觉像 md5 那样,前后的公用一套加密解码规则,后端在接受上传图片的时候生成,然后前端接受这个 hash 去实现渐进式加载,似乎还自带了性能优化(原理是精装版 base64 么?)

😂我看明白后,再问问主管后面优化版本能不能搞这个。这期我做的上文所述的改动,是纯前端的实现,改动很小,还没去唠嗑后端同事哩
devwolf
2021-11-29 15:36:53 +08:00
@murmur 谷歌调低端设备就能看到啦(我也是下午才知道能调这个)
devwolf
2021-11-29 16:20:16 +08:00
@sdqhzhm 😂确实是相关且相似的概念,但后台的图片上传是放开图片类型的,不仅有 jpeg,下午后来就没再深究了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/818727

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX