Preload图片预加载(jQuery插件)

背景

我们在做页面的时候,从用户体验的角度出发,肯定是希望用户以最快的速度看到完整的页面信息,但在实际情况中经常会遇到些问题。

比如受网速影响,页面加载素材的时间比较长,页面会出现短时间的错乱或者闪屏;

或者页面素材比较多、比较大,需要一定的加载时间,特别有时候的活动页面,我们一般会把首屏做的更多多样化或者传达比较丰富的氛围的时候,我们的首屏素材上都会比较大,有时候也会给元素加上动画来传达信息,比如我之前做的WeGame新春活动页就是这样的情况;

一般我们的处理方案是在页面素材加载完成之前显示一个有趣(不那么枯燥)的loading页,那么从重构的角度出发,我们这个素材加载状态该怎么配合loading页做处理呢,于是想到了可以监测一下浏览器加载图片的状态,并同时响应处理,比如加载完时隐藏loading页,每加载完一张图片就更新加载的百分比进度条等。

当然,值得注意的是,我们应该尽量的让用户等待loading页的时间变短,因为不要忘了,loading页也只是向后兼容处理的方案,它本身不是必须存在的。

方案分析

**场景:**除了首屏loading页加载必须的图片之外(无序加载),可能还有其他情景比如漫画网站,需要加载完前一张图片再加载下一张(有序加载)

原理:通过image 的 onload 事件判断浏览器加载图片的状态。

实现:一般我们会这样处理:

 var img = new Image();
 img.src = "logo.jpg";
 img.onload = function () {
    alert("image is loaded");
 };

但是这样处理有点问题,首先我们来认识两点:

1.一旦Image对象设置了src值,浏览器就会向服务器发起请求,并缓存返回的图片。

2.浏览器请求是异步的。也就是说这段代码会遍历数组,每张图片几乎同时发起请求,并不需要等待服务器返回结果后顺序发起请求。就是说,js不会傻傻地在原地等待图片的加载,而是继续读代码,直到图片加载完成,触发onload事件,js才会回来执行onload里面的内容。

基于以上两点,如果我们先赋值了图片地址,浏览器已经加载完成的时候,onload绑定事件还没有赋值上去,这样就造成了一定的误差,所以改进如下:

 var img = new Image();
 img.onload = function () {
    alert("image is loaded");
 };
 img.src = "logo.jpg";

先绑定事件,在赋值图片地址,确保浏览器发起请求前,图片已经绑定了onload事件。

Preload插件实现

GitHub地址:https://github.com/xiangshuo1992/preload

/**
 * 图片预加载插件Preload
 *
 * @param array imgs  预加载的图片地址数组列表
 * @param Object options  配置参数
 */

(function ($) {
    function Preload(imgs, options) {
        this.imgs = (typeof imgs === ‘string‘) ? [imgs] : imgs;
        this.options = {
            order: false, //默认值false,代表无序加载
            minTimer: 0, //完成加载的最少时间,单位ms,默认为0,一般展示类型的loading动画会需要设置
            each: null, //单张图片加载完执行的方法,一般是修改进度状态
            end: null //所有图片加载完执行的方法,一般是隐藏loading页
        };
        this.timer = Date.now();
        this.init(options);
    };
    //插件初始化
    Preload.prototype.init = function (options) {
        //配置参数合并
        this.options = $.extend(this.options, options);
        if (this.options.order) {
            this.ordered(); //有序加载
        } else {
            this.unordered(); //无序加载
        }
    };
    // 有序加载
    Preload.prototype.ordered = function () {
        var that = this,
            imgs = this.imgs,
            len = imgs.length,
            count = 0,
            options = this.options;
        load();

        function load() {
            var img = new Image();
            $(img).on(‘load error‘, function () {
                options.each && options.each(count);
                if (count >= len-1) {
                    //所有图片加载完毕,检查是否满足最小loading时间
                    var timerCount = Date.now() - that.timer;
                    if (timerCount < options.minTimer) {
                        var timeout = options.minTimer - timerCount;
                        setTimeout(function () {
                            options.end && options.end();
                        }, timeout);
                    }else{
                        options.end && options.end();
                    }
                } else {
                    load();
                }
                count++

            });
            // onload函数要写在改变src前,这样确保了onload函数一定会被调用

            img.src = imgs[count];
        }
    };
    // 无序加载
    Preload.prototype.unordered = function () {
        var that = this,
            imgs = this.imgs,
            len = imgs.length,
            count = 0,
            options = this.options;
        for (var i = 0; i < len; i++) {
            var img = new Image();
            $(img).on(‘load error‘, function () {
                options.each && options.each(count);
                if (count >= len-1) {
                    //所有图片加载完毕,检查是否满足最小loading时间
                    var timerCount = Date.now() - that.timer;
                    if (timerCount < options.minTimer) {
                        var timeout = options.minTimer - timerCount;
                        setTimeout(function () {
                            options.end && options.end();
                        }, timeout);
                    }else{
                        options.end && options.end();
                    }
                }
                count++;
            })
            img.src = imgs[i];
        }
    };
    //扩展到jQuery对象上
    $.extend($,{
        preload: function (imgs, options) {
            new Preload(imgs, options);
        }
    });
})(jQuery);

有序加载和无序加载

无序加载:前面我们说了,浏览器请求是异步的,所以我们的资源请求有可能是同时在加载过程中。
我用chrome浏览器的开发者工具,查看了无序加载时,图片的加载状态如下:

可以看到,会出现同时请求多张图片的情况,也就是说当我们希望所有的网速集中在一张图片上时,这个方案是不行的,于是就有了有序加载。

有序加载:前面我们是通过循环来实现无序加载的,我们要先实现图片资源有序加载,就需要在当前图片加载完成时才去加载下一张图片,这里我们用函数回调实现,虽然整个资源的加载时间变长了,但是却也保证了图片是有序出现的,在上面说的漫画网站的场景下非常适用。
我用chrome浏览器的开发者工具,查看了无序加载时,图片的加载状态如下:

总结

上面我们分析和实现了一个看起来非常简单,但是也包含了不少内容的图片预加载插件,从业务场景、方案分析、代码实现、说明文档、测试使用、总结输出这一系列的流程,我知道了,实现一个插件可简单,可复杂,可轻量,可丰富,不管怎样,任何的实现都是基于满足自己和团队的使用,合适的就是最好的。

最后,也希望能给大家提供一点帮助,如有建议,欢迎留言!

原文地址:https://www.cnblogs.com/sttchengfei/p/12324768.html

时间: 2024-10-07 15:57:51

Preload图片预加载(jQuery插件)的相关文章

闭包,jQuery插件的写法:图片预加载

最近做的一些网页,单个网页图片量都比较大,网络不好的情况下,特别卡,这个图片预加载的方法可以牺牲一些时间换来网页的浏览顺畅,还是值得的. //闭包的写法,它内部的变量都是局部的,不会和外部巳有的变量进行冲突 ( function (通过它来接收对象) { } )( 通过它来传递对象 ); //可以使用jQuery的$符号的闭包插件的写法: //写插件的常用方法 $.extentd() (function ($){ //构造函数 function PreLoad(imgs,options){ th

jquery.imgpreload.min.js插件实现页面图片预加载

页面分享地址: http://wenku.baidu.com/link?url=_-G8miwbgDmEj6miyFtjit1duJggBCJmFjR2jky_G1VftD9eS9kwGOlFWAORk2_fotM4RbzRvtcaiQu2y_BU3Gpj0rYRy_EWrgXEuFeja0q 页面分享地址:http://www.jb51.net/article/21987.htm Javascript , Jquery 实现页面图片预加载百分比展现 如果需要在页面初始加载时显示加载进度.主要是

【JQuery插件】图片预加载

屏幕滚动到图片当前位置加载图片,给需要预加载的图片设置一个data-url的属性即可. ;(function($){ /* 图片预加载 @author liuming @demo $('img[data-url]').ImgLoading(); */ $.fn.ImgLoading=function(){ var aImgs =$(this),/*缓存图片列表*/ $win = $(window), img,imgTop, winH = $win.height(), Timmer=null, i

jquery实现图片预加载

使用jquery实现图片预加载提高页面加载速度和用户体,本就为大家详细分析jquery图片预加载的实现原理. 什么时候使用图片预加载? 如果页面使用了很多不是最初加载便可见的图片,有必要进行预加载: $.preloadImages = function () { for (var i = 0; i < arguments.length; i++) { $('img').attr('src', arguments[i]); }};$.preloadImages('img/hover-on.png'

jQuery图片预加载

jQuery图片预加载早已不是什么新鲜的技术,比如在图片轮播(一些hover事件中)时为了提高图片加载速度,这就需要用到图片预加载技术,这样图片的切换就显得流畅,这样做一定意义上提升了用户体验.我们简单看看实现方法及简单的说明:UI前端框架最新力作!有奖试读 .代码   var img = $('<img />').attr('src', 'imageurl.jpg'); jQuery创建了一个图片元素并设置了它的地址,如果将它放在document ready中处理时,当页面加载时就会告诉浏览

jquery实现图片预加载提高页面加载速度

使用jquery实现图片预加载提高页面加载速度和用户体 我们在做网站的时候经常会遇到这样的问题:一个页面有大量的图片导致页面加载速度缓慢,经常会出现一个白页用户体验很不好.那么如何解决这个问题 呢?首先我们会想到的是提高服务器性能,使用静态缓存等手段来加快图片的加载速度,这的确是个好方法,不过有时候我们也可以从前台找一些解决的 方法.下面我来介绍一种在实际应用中经常会使用到的js预加载的方法. 首先在输出图片的时候我们做一些处理 处理完html我们开始写js了,在这里我使用了jquery的类库

利用简洁的图片预加载组件提升h5移动页面的用户体验

在做h5移动页面,相信大家一定碰到过页面已经打开,但是里面的图片还未加载出来的情况,这种问题虽然不影响页面的功能,但是不利于用户体验.抛开网速的原因,解决这个问题有多方面的思路:最基本的,要从http请求合并,缓存管理,图片压缩等方面做性能优化:另外就是可以对页面里用到的所有图片做预加载的处理,当用户打开页面的时候不立即显示第一屏,而是先显示资源加载效果,等到加载完毕,再来显示页面的主内容,这样就能解决那个问题.虽然这种加载效果占用了用户的浏览时间,但是我们可以把它做的好看有趣一点,所以也不会影

图片预加载与懒加载

预加载与懒加载,我们经常经常用到,这些技术不仅仅限于图片加载,我们今天讨论的是图片加载: 一.什么是图片预加载与懒加载: 图片预加载:顾名思义,图片预加载就是在网页全部加载之前,提前加载图片.当用户需要查看时可直接从本地缓存中渲染,以提供给用户更好的体验,减少等待的时间.否则,如果一个页面的内容过于庞大,没有使用预加载技术的页面就会长时间的展现为一片空白,这样浏览者可能以为图片预览慢而没兴趣浏览,把网页关掉,这时,就需要图片预加载.当然这种做法实际上牺牲了服务器的性能换取了更好的用户体验. 图

关于图片预加载的思考

引子: 很多时候,我们在写html页面的时候,当需要在页面中加入图片时,我们很自然地把图片直接用<img>标签放在了<body>里面,这本来是没有多大问题的. 但是当图片数量很多的时候,问题就来了.Html页面在被解析器解析的时候要不断去寻找图片的路径去加载图片,而这些图片不一定所以都会被用户通过触发一些类似点击的操作所看到.这样,一些不必要的图片预加载就会拉长了页面的加载时间,带来的用户体验是不好的. 为了解决这个性能问题,有一个比较好的解决问题就是用js去延迟图片预加载.那么具