前端性能优化之jQuery按需加载轮播图

引言

关于幻灯轮播图,想必你们都不陌生,尤为是基于 jQuery 的,插件、代码网上一搜一大堆,可是真正符合本身需求的几乎没有,因此我要打造一个符合自身需求,经得起广大网民考验的 jQuery 轮播图!css

思路

为何说网上其余一些轮播图不符合个人要求?个人需求又是什么呢?html

如今网上能够找到的多数幻灯轮播图的 jQuery 插件的做法是,先把图片和连接的 HTML 写好,而后控制隐藏和显示来轮流展现当前的幻灯图片。可是对用户而言,咱们始终只是看到当前的一张图片,那其余几张隐藏的图片为何要事先加载进来呢?这不是费时费力吗?因此个人第一个需求是按需加载。web

咱们通常会把轮播图放在首页展现,可是首页的重点内容应该是最近更新的文章,至少我不认为图片展现功能须要被搜索引擎收录,因此个人第二个需求是符合 SEO。浏览器

实现

冲着以上两个需求,我作了一个 DEMO,你们不妨看看这个 DEMO 的源代码,发现区别了吗?是的,在这个 DEMO 的 HTML 源代码中,你看不到任何的图片和相关信息,都由 JS 载入进来的,也就是说爬虫爬不到,并且是随着图片的切换,一张一张地载入当前的幻灯图片。网络

这里我就只分享一下个人 JS 写法,HTML 什么就请各位看源码吧,代码我就不一一细说了,注释也都写得很明白了。app


$(function() {
    var WangeSlide = (function() {
        //配置
        var config = {
            //轮播图尺寸
            width : 960,
            height : 350,
            //是否自动切换
            autoSwitch : true,
            //自动切换间隔时间(毫秒)
            interval : 6000,
            //轮播图图片路径
            picPath : 'http://www.dowebok.com/demo/2014/93/img/',
            //轮播图图片信息:图片文件名 / 图片标题 / 图片指向连接
            picInfo : [
                ['fullimage1.jpg', '图片1提示','http://codepen.io/webstermobile/'],
                ['fullimage1.jpg', '图片2提示','http://codepen.io/webstermobile/'],
                ['fullimage1.jpg', '图片3提示','http://codepen.io/webstermobile/']
            ]
        };
        //获取图片信息
        /**
         * @param index 图片所在的索引值
        **/
        var getImgInfo = function(index) {
            var imgSrc = config.picPath + config.picInfo[index][0],
                imgAlt = config.picInfo[index][3],
                imgUrl = config.picInfo[index][4],
                imgId = 'slide_' + (index+1).toString(),
                imgHtml = '<li id="' + imgId + '">' +
                            '    <a href="' + imgUrl +'" title="' + imgAlt + '" class="pic">' +
                            '        <img src="' + imgSrc + '" alt="' + imgAlt + '" class="slide_thumb" />' +
                            '    </a>' +
                        '</li>',
                slideTextHtml = '<a href="' + imgUrl + '"  title="' + imgAlt + '">' + imgAlt+ '</a>';
            return {
                imgAlt : imgAlt,
                imgUrl : imgUrl,
                imgHtml : imgHtml,
                slideTextHtml : slideTextHtml
            }
        };
        
        //图片彻底加载后缓慢加载显示
        var fadeInImg = function(el, speed) {
            //console.log(el)
            el.find("img").load(function() {
                el.find("img").addClass("loaded")
                el.fadeIn(speed)
            });
        };
        
        //图片切换
        /**
         * @param index 图片所在的索引值
         * @param triggerCurEl 当前触发节点元素
        **/
        var imgSwitch = function(index, triggerCurEl) {
            var slideId = 'slide_' + (index+1).toString(),
                slideIdEl = document.getElementById(slideId);
            if (slideIdEl) {
                //若是已有对应的元素,则显示已有元素
                var panelLi = $('#panel ul li');
                panelLi.hide();
                $(slideIdEl).fadeIn('slow');
            } else {
                //若是尚未对应的元素,则注入元素
                $(getImgInfo(index).imgHtml).appendTo($('#panel ul'));
                var panelLi = $('#panel ul li');
                panelLi.hide();
                //载入显示图片
                fadeInImg($("#" +slideId), 'slow');
            }
            
            //获取图片的 alt 做为显示信息
           $('#slide_text').html(getImgInfo(index).slideTextHtml);
            
            //当前状态 cur
            $('#trigger ul li').removeClass('cur');
            triggerCurEl.addClass('cur');
        };
        
        //轮播图
        var slide = function() {
            //设置轮播图尺寸
            $('#panel').css({
                'width' : config.width + 'px',
                'height' : config.height + 'px'
            });
            var result = getImgInfo(0).imgHtml
            //初使化轮播图,只加载第一张图片信息
            $('#panel ul').html($(result));
            //载入显示图片
            fadeInImg($('#slide_1'), 500);
            
            //注入背景层 + 触发器容器 + 轮播图文字容器
            var slideBg = '<div id="slide_bg"></div>',
                trigger = '<div id="trigger"></div>',
                slideText = '<div id="slide_text"></div>';
            $('#panel').after(slideBg + trigger + slideText);
            
            //获取图片的 alt 做为显示信息
            $('#slide_text').html(getImgInfo(0).slideTextHtml);
            
            //注入触发节点
            var triggerUl = $('<ul></ul>');
            triggerUl.appendTo($('#trigger'));
            for (var i=0, j=config.picInfo; i<j.length; i++) {
                $('<li>' + (i+1).toString() +'</li>').appendTo(triggerUl);
            }
            
            //当前状态 cur
            $('#trigger ul li').eq(0).addClass('cur');
            //点击触发节点
            $("#trigger ul li").click(function(){
                var index = $("#trigger ul li").index($(this))
                //console.log(index)
                imgSwitch(index,$(this))
            })
            
            
            //鼠标悬停时,中止切换
            var goSwitch = true;
            $('#panel').hover(
                function() {goSwitch = false},
                function() {goSwitch = true}
            );
            
            //自动切换
            if (config.autoSwitch) {
                setInterval(function() {
                    if (goSwitch) {
                        //判断当前cur所在的索引值
                        var index = parseInt($('.cur','#trigger').text()) - 1;
                        if (index > (config.picInfo.length-2)) {
                            index = -1;
                        }
                        imgSwitch((index+1), $('#trigger ul li:eq(' + (index+1) + ')'));
                    }
                }, config.interval);
            }
        };
        
        return {
            //初使化
            init : function() {
                slide();
            }
        }
    })();
    
    WangeSlide.init();

})

按需加载的网络请求状况

图片描述
从图上能够看到页面加载的时候自动切换或者用户点击切换以前只加载了一张slide图,大大节省了页面加载量。ide

优点

一样的效果,只是实现方法不一样?会不会很蛋疼?这有什么优点呢?优化

举个例子来讲,优化前,假设首页切换的幻灯图片有5张,平均每张图片20K,也就是说你的首页至少要加载100K的图片,而这100K的图片你能保证每一个用户都会去看吗?若是用户不看,岂不是白白浪费了这100K的载入速度?this

优化后,在首页初次载入的时候,仅需加载一张1K左右的,甚至是无关紧要的 loading 图片,当用户点击下一张或者达到定时器的设置时才会去加载下一张图片,大大节省了载入的时间。1K?100K?你懂的。搜索引擎

另外,用 JS 载入所需的图片还有一个好处,就是在一些不支持 JS 的手机浏览器上,载入 100K 的图片对于没法切换的轮播图而言,是一个极大的累赘,并且也会大大下降用户体验。

好了,你们各取所需吧,我也只是提供了一个思路,若是有更好的实现方法欢迎与我交流。

相关文章
相关标签/搜索