V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
sneezry
V2EX  ›  分享创造

延时加载图片

  •  
  •   sneezry ·
    Sneezry · 2015-09-14 12:05:10 +08:00 · 3323 次点击
    这是一个创建于 3357 天前的主题,其中的信息可能已经有所发展或是发生改变。

    为什么要延时加载图片

    正常情况下,网页中的图片是随着 DOM 流加载的,这样有两个问题:

    1 、图片没有下载完成就显示出来,造成显示时图片不完整,用户网络环境恶劣时体验糟糕。

    2 、一个页面存在多个图片时,浏览器是并行下载的,并不能保证在页面前面的图片就先显示出来,所以更应该让页面前面的图片先加载,尽快给用户展示一个完整的页面,而页面后面的图片就可以慢慢加载。

    3 、当用户硬性刷新页面时,延时加载图片可以做到依然读取缓存,这样可以减少不必要的 CDN 流量。

    项目地址: https://github.com/Sneezry/image-delay.js

    Live Demo : http://sneezry.github.io/image-delay.js/example/

    查看 Demo 时打开 Chrome 控制台,在 Networking 中将网络环境模拟成比较糟糕的情况(比如 Good 3G )可以更加清晰地看到加载过程,同时尝试硬性加载,可以看到后面几幅图片都是从缓存中读取的。

    MIT License.

    20 条回复    2015-09-16 11:20:45 +08:00
    pein
        1
    pein  
       2015-09-14 12:17:54 +08:00
    图片延时加载和图片预加载( new Image ())哪个比较好?使用效果上来说貌似是差不多的。
    sneezry
        2
    sneezry  
    OP
       2015-09-14 12:33:26 +08:00 via iPhone
    @pein 原理是一样的,重点是加载开始的时间点,预加载如果不做特殊处理也是和 DOM 里的图一起抢资源
    X-Force
        3
    X-Force  
       2015-09-14 12:36:36 +08:00
    这个可以和 srcset 兼得么?
    sneezry
        4
    sneezry  
    OP
       2015-09-14 12:43:50 +08:00
    @X-Force 目前只做了 CSS 中的 -webkit-image-set 兼容, srcset 我会加进去的,不过得先研究下优先级
    sneezry
        5
    sneezry  
    OP
       2015-09-14 12:51:58 +08:00
    @X-Force 啊,我理解错了,支持起来似乎并不麻烦,现在应该已经支持了,用 data-delay-setsrc 就可以了
    pein
        6
    pein  
       2015-09-14 14:35:06 +08:00
    看了下 js 文件,有几个问题想问一下
    1 , background 图片可通过增加 data-image-delay-wait 来实现图片“加载完成后显示”,但似乎没有看到检测图片是否加载完毕的代码,只有 onload 事件,没有 complete?
    2 , background 图片可通过增加 data-image-delay-wait 来实现图片“加载完成后显示”,但<img>似乎只有延迟(顺序)加载而没有“完成后显示”功能?
    3 ,文件最底下为什么有两个 setTimeout ?
    上述的问题可能会导致,如果图片很大的话,应该还是会出现图片显示一半的情况(没实际测过,猜的)。
    sneezry
        7
    sneezry  
    OP
       2015-09-14 15:11:05 +08:00
    @pein 感谢反馈 :-D

    1 , onload 是个通用的做法, complete 需要轮询(如果有错误请指出)

    2 , img 标签没有提供 data-image-delay-wait 方法,后续我会扩充 :-D

    3 ,第一个 setTimeout 是为了达到强刷延时加载图片依然走缓存的目的,第二个是防止 window.onload 不触发导致图片不加载的问题,第二个延时时间可以通过 html 标签的 data-delay-timeout 属性设置

    图片过大确实会出现显示一半的情况, live demo 里就出现了,哈哈
    imxz
        8
    imxz  
       2015-09-14 15:12:15 +08:00
    有个 lazyload 貌似实现了同样的效果
    flyz
        9
    flyz  
       2015-09-14 15:15:59 +08:00
    总觉得花瓣的效果最赞。
    sneezry
        10
    sneezry  
    OP
       2015-09-14 15:25:24 +08:00
    @imxz lazyload 是一个非常出色的作品,它不仅仅支持图像的惰性加载,甚至还支持框架的惰性加载。但是遗憾的是 lazyload 并没有针对图像延时加载做过多优化, lazyload 更适合长页面的应用场景,另外好像也没有对背景图片做支持,希望 lazyload 和 image-delay.js 协同起来能给大家带来更大的便利 :-D
    pein
        11
    pein  
       2015-09-14 15:32:49 +08:00
    @sneezry 嗯,看代码这个确实能做到顺序加载,但是“加载完显示”问题不解决的话,直观上来说顺序显示图片是做不到的,因为先加载的不一定就先显示,比如前面的图片大后面的小,就可能导致后加载的图片反而先显示,而且前面图片加载一半的情况也会出现。想象一下:前面的大图加载了一半,中间的一片空白还没加载,后面的小图都加载完了。。。
    sneezry
        12
    sneezry  
    OP
       2015-09-14 15:36:49 +08:00
    @pein 确实是这样的,苹果的做法是把 DOM 的框架做好,这样不会出现出一张图,整体布局串一下。但是苹果没有做顺序加载,而是做了并行加载,原因是使用了延时加载的图都在页面的后半部分,很少有用户打开页面就马上往下滚动。并行加载的好处是速度快,缺点就是提到的加载完成顺序不可控。我会继续优化,增加顺序加载和加载完成后再显示的属性的 :-D
    popok
        13
    popok  
       2015-09-14 16:23:53 +08:00 via iPhone
    @X-Force 异次元站长?
    seyang1025
        14
    seyang1025  
       2015-09-14 17:33:39 +08:00
    不都是 加载当前么,当前在哪个位置,就加载哪里
    g0thic
        15
    g0thic  
       2015-09-14 19:01:14 +08:00
    不错,英语真 binag
    wsph123
        16
    wsph123  
       2015-09-14 21:19:58 +08:00   ❤️ 1
    点击浏览器后退按钮时 可能会跳过 onload 事件,这时候需要通过 complete 进行判断是否已经载入成功
    sneezry
        17
    sneezry  
    OP
       2015-09-14 22:27:02 +08:00
    @wsph123 感谢 :-D
    crs0910
        18
    crs0910  
       2015-09-16 08:39:59 +08:00
    lz 请教个问题,类似 img 标签的 lowsrc 属性,实现如果 background 图片太大的话,先加载较小的图片,等大图下载完之后再替换应该怎么搞。写两个 class 吗?
    sneezry
        19
    sneezry  
    OP
       2015-09-16 09:43:33 +08:00 via iPhone
    @crs0910 没用过,似乎兼容性不太好,不过我觉得不用做多余的处理,浏览器能够自己处理好
    zqjilove
        20
    zqjilove  
       2015-09-16 11:20:45 +08:00
    看着感觉用起来很麻烦的感觉
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2785 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 11:33 · PVG 19:33 · LAX 03:33 · JFK 06:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.