美文网首页
Web图片加载

Web图片加载

作者: YangEric | 来源:发表于2016-11-11 16:30 被阅读0次

Web端的性能优化很多都集中在对JavaScript和CSS上面,比如"Move Scripts to the Bottom","Put Stylesheets at the Top"等等,很多时候,我们的开发中会忽略掉,图片的优化其实也是非常重要的一部分。

我们关注JS和CSS的重点也是如何能够更快地下载图片。图片是用户可以直观看到的,他们并不会关注JS和CSS。

以最近做的一个页面同花顺理财周为例:

xhr img css/js doc 其他
Size(kb) 1.216 52.331 22 4.8 0
Time(ms) 453 1628 822 164 0

web端的图片加载

在开始本文的介绍之前,先了解一些基础的知识:
在网页中插入一张图片可以使用html的<img>标签[站外图片上传中……(2)],每插入新建一个<img>标签就会新建一个Image 对象。
Image 对象的属性 onload 声明了一个事件句柄函数,当图像装载完毕的时候就会调用这个句柄。
Image 对象的属性 onerror 声明了一个事件句柄函数,当装载图像的过程中发生了错误时就会调用这个句柄。

我们目前在页面中采取的两种加载方式

针对首屏的banner图

<!-- html -->
[站外图片上传中……(2)]

<!-- js -->
function load_img(url, url_s, o) {
    var img = new Image(); //创建一个Image对象,实现图片的预下载
    img.src = url;
    o.src = url_s;

    if (img.complete) { //图片已经被缓存,直接替换
        o.src = img.src;
        return;
    };

    img.onload = function() { //图片下载完毕时替换
        o.src = img.src;
    };
};

load_img(("images/header.png"), ("images/header.jpg"), document.getElementById("img_init"));

原理:用一张很小的图片A替换清晰banner图B优先加载,然后js新建源为图B的Image对象并监控其加载进度,当图B加载完成之后,再替换掉图A。
不足:

  • 功能单一,只能实现单张图片的预加载
  • 只考虑了静态图片的加载,忽略了gif等动态图片,这些动态图片可能会多次触发onload
  • 必须等待图片加载完毕, 仍然有优化空间

滚屏加载(图片的异步加载)

<!-- html -->
[站外图片上传中……(3)]

<!-- js -->
function timeOutLoad(container) {
    this.container = container || document;
    var imgs = [],_num = [];
    var oriImgs = this.container.getElementsByClassName('timeOutLoad');
    for (var i = 0; i < oriImgs.length; i++) {
        var _data = oriImgs[i].getAttribute("data-original");
        if (_data) {
            _num.push(i);
            imgs.push(_data);
        }
    }
    function loadByOne(i) {
        if (imgs.length > 0) {
            _img = new Image();
            _img.onload = function () {
                oriImgs[_num[i]].setAttribute('src', _img.src);
                oriImgs[_num[i]].removeAttribute('data-original');
                loadByOne(i + 1);
            };
            _img.src = imgs.shift();
        }
    }
    loadByOne(0);
}
timeOutLoad(document.getElementById("container"));
原理:

通过判断当图片元素是否出现在视窗范围内后,则去加载图片资源,否则不加载。

延伸

Litten说到加载图片,我们可以谈些什么

特殊状态处理

  • 加载中:在图片开始加载到触发onliad事件之前,展示加载的loading图
  • 加载失败:文字提示,或错误提示图片替代

上报监控

  • 加载失败触发onerror时,上报统计每天图片拉取失败的量
  • 图片加载事件过长,上报分析cdn服务是否异常,或者是网速较慢的用户比例

webp

smaller、*richer *

一个较完善的可行方案

花落红尘 诺诶网络

// 更新:
// 05.27: 1、保证回调执行顺序:error > ready > load;2、回调函数this指向img本身
// 04-02: 1、增加图片完全加载后的回调 2、提高性能

/**
 * 图片头数据加载就绪事件 - 更快获取图片尺寸
 * @version    2011.05.27
 * @author    TangBin
 * @see        http://www.planeart.cn/?p=1121
 * @param    {String}    图片路径
 * @param    {Function}    尺寸就绪
 * @param    {Function}    加载完毕 (可选)
 * @param    {Function}    加载错误 (可选)
 * @example imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function () {
        alert('size ready: width=' + this.width + '; height=' + this.height);
    });
 */
var imgReady = (function () {
    var list = [], intervalId = null,

    // 用来执行队列
    tick = function () {
        var i = 0;
        for (; i < list.length; i++) {
            list[i].end ? list.splice(i--, 1) : list[i]();
        };
        !list.length && stop();
    },

    // 停止所有定时器队列
    stop = function () {
        clearInterval(intervalId);
        intervalId = null;
    };

    return function (url, ready, ,load error) {
        var onready, width, height, newWidth, newHeight,
            img = new Image();
        
        img.src = url;

        // 如果图片被缓存,则直接返回缓存数据
        if (img.complete) {
            ready.call(img);
            load && load.call(img);
            return;
        };
        
        width = img.width;
        height = img.height;
        
        // 加载错误后的事件
        img.onerror = function () {
            error && error.call(img);
            onready.end = true;
            img = img.onload = img.onerror = null;
        };
        
        // 图片尺寸就绪
        onready = function () {
            newWidth = img.width;
            newHeight = img.height;
            if (newWidth !== width || newHeight !== height ||
                // 如果图片已经在其他地方加载可使用面积检测
                newWidth * newHeight > 1024
            ) {
                ready.call(img);
                onready.end = true;
            };
        };
        onready();
        
        // 完全加载完毕的事件
        img.onload = function () {
            // onload在定时器时间差范围内可能比onready快
            // 这里进行检查并保证onready优先执行
            !onready.end && onready();
        
            load && load.call(img);
            
            // IE gif动画会循环执行onload,置空onload即可
            img = img.onload = img.onerror = null;
        };

        // 加入队列中定期执行
        if (!onready.end) {
            list.push(onready);
            // 无论何时只允许出现一个定时器,减少浏览器性能损耗
            if (intervalId === null) intervalId = setInterval(tick, 40);
        };
    };
})();

调用案例:

imgReady('http://www.google.com.hk/intl/zh-CN/images/logo_cn.png', function (){
    alert('size ready: width=' + this.width + '; height=' + this.height);
});

相关文章

  • Web图片加载

    Web端的性能优化很多都集中在对JavaScript和CSS上面,比如"Move Scripts to the B...

  • Canvas下

    一、绘制img/video图片预加载,获取图片文件,顾名思义,WEB中的预加载就是在网页全部加载之前,对一些主要内...

  • 瀑布流图片以及预加载

    在web项目开发中,经常遇到需要加载大量的图片,为了�提高用户体验,我们可以使用预加载技术把图片预先加载到浏览器中...

  • canvas图片懒加载

    整理一下从别处学来的一种图片懒加载的方式。 什么是图片懒加载,简单来说就是在web应用中,图片不会一次性全部加载,...

  • 【web性能】图片の加载

    就像一些商城首页,或者浏览性展示性的网站中,需要给用户展示大量图片内容??;对应的当然也需要有一些针对性的性能优化...

  • 图片延迟加载代码分析

    最近在写在手机上运行的web项目,固然要考虑到图片加载的问题,以尽可能的减少图片的加载量,在这里,就用到了图片延迟...

  • SDWebImage原理

    一个为UIImageView提供一个分类来支持远程服务器图片加载的库。功能简介: 一个添加了web图片加载和缓存管...

  • JS中的图片预加载原理及运用的小案例

    相信大家在 接触到图片预加载时,都会有很多疑问,图片预加载有什么用处,它的原理是什么,以及它是如何提高web性能的...

  • # 懒加载和预加载

    web前端 1. 懒加载 1、不加载全部图片 2、首先显示在页面中的图,首先进行加载 3、当屏幕发生滚动的时候,判...

  • android 圆角图片与更换图片

    涉及圆角与图片web加载,使用fresco 在build.gradle添加依赖 在使用imageview的地方使用...

网友评论

      本文标题:Web图片加载

      本文链接:https://www.haomeiwen.com/subject/xvyfpttx.html