V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
devwolf
V2EX  ›  前端开发

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

  •  
  •   devwolf ·
    yctjb1 · 2021-11-29 14:03:11 +08:00 · 1518 次点击
    这是一个创建于 850 天前的主题,其中的信息可能已经有所发展或是发生改变。
    以下仅我盲人摸象式的总结,主要是希望 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
    上周在“能不能只靠前端实现”这个环节调研了好久,
    结果上而言确实不用后端同事协助……那个图片处理似乎是别处提供的
    12 条回复    2021-11-29 16:20:16 +08:00
    murmur
        1
    murmur  
       2021-11-29 14:09:09 +08:00
    那种所谓渐进式加载好像是 png 的格式决定的,有两种,一种是从完整到不完整,一种是从糊到清晰

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

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

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

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

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

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

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

    😂我看明白后,再问问主管后面优化版本能不能搞这个。这期我做的上文所述的改动,是纯前端的实现,改动很小,还没去唠嗑后端同事哩
    devwolf
        11
    devwolf  
    OP
       2021-11-29 15:36:53 +08:00
    @murmur 谷歌调低端设备就能看到啦(我也是下午才知道能调这个)
    devwolf
        12
    devwolf  
    OP
       2021-11-29 16:20:16 +08:00
    @sdqhzhm 😂确实是相关且相似的概念,但后台的图片上传是放开图片类型的,不仅有 jpeg,下午后来就没再深究了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1018 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 19:43 · PVG 03:43 · LAX 12:43 · JFK 15:43
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.