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

瘢痂协程
• 阅读 4266

引言

关于幻灯轮播图,想必大家都不陌生,尤其是基于 jQuery 的,插件、代码网上一搜一大堆,但是真正符合自己需求的几乎没有,所以我要打造一个符合自身需求,经得起广大网民考验的 jQuery 轮播图!

思路

为什么说网上其他一些轮播图不符合我的要求?我的需求又是什么呢?

现在网上可以找到的多数幻灯轮播图的 jQuery 插件的作法是,先把图片和链接的 HTML 写好,然后控制隐藏和显示来轮流展示当前的幻灯图片。但是对用户而言,我们始终只是看到当前的一张图片,那其他几张隐藏的图片为什么要事先加载进来呢?这不是费时费力吗?所以我的第一个需求是按需加载。

我们一般会把轮播图放在首页展示,但是首页的重点内容应该是最近更新的文章,至少我不认为图片展示功能需要被搜索引擎收录,所以我的第二个需求是符合 SEO。

实现

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

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


$(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();

})

按需加载的网络请求情况

前端性能优化之jQuery按需加载轮播图
从图上可以看到页面加载的时候自动切换或者用户点击切换之前只加载了一张slide图,大大节省了页面加载量。

优势

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

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

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

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

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

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
CuterCorley CuterCorley
4年前
Django+Vue开发生鲜电商平台之11.首页、商品数量、缓存和限速功能开发
青,取之于蓝而青于蓝;冰,水为之而寒于水。——《荀子·劝学》Github和Gitee代码同步更新:;。一、首页功能完善首页待完善的功能包括轮播图、新品尝鲜、系列商品等。1.轮播图实现轮播图包括3张图片,链接对应3个商品,先在apps/goods/serializers.py中定义序列化如下:pythonclassBanner
红橙Darren 红橙Darren
4年前
RecyclerView更全解析之 - 为它优雅的添加头部和底部
1.概述上一期的,解决了几个坑。那么这一期我们来动态为RecyclerView去加载头部和底部,为上一期的RecyclerView列表数据添加广告轮播图,至于广告轮播大家可以看一下这一期,这里我就不多讲了,直接拿过来用。    视频讲解:相关文章:                        
Stella981 Stella981
3年前
JTopo + Vue 实现自定义拖拽流程图
JTopoVue实现自定义拖拽流程图市场上做流程图的插件比较多,这里介绍一种基于canvas编写的js插件,结合vue框架做出精美的流程图首先搭建vue框架,这里就不做介绍,由于jtopo官方demo里用到了jquery,所以我的项目里也引用了jquery插件,鉴于这里用到了很多的dom操作,所
Stella981 Stella981
3年前
Javascript使用三大家族和事件来DIY动画效果相关笔记(四)
1.图片轮播基础之缓速轮播◆使用封装的缓慢速动画来DIY滑动轮播图,也就是鼠标移动到123456这些数字上后,图片以缓慢速滑动的方式进行切换。<!DOCTYPEhtml<htmllang"en"<head<metacharset"UTF8"<title使用封装的缓速
Stella981 Stella981
3年前
Android开发工程师文集
Android开发工程师文集Fragment,适配器,轮播图,ScrollView,Gallery图片浏览器,Android常用布局样式FragmentFragmentManagerfragmentManagergetFragmentManager();FragmentTransactionbeg
Wesley13 Wesley13
3年前
JS实现小图放大轮播效果
JS实现小图放大轮播页面效果入下(图片为优行商旅页面照片):!(https://oscimg.oschina.net/oscnet/fea423c49d5f7430375068501d3f032d631.png) 实现效果:图片自动轮播,鼠标移入停止,移出继续轮播点击下方小图可以实现切换步骤一:建立HTML布局,具体
程序员一鸣 程序员一鸣
2个月前
HarmonyOs开发:轮播图Banner组件封装与使用
轮播图在每个项目中都很常见,鸿蒙中在容器组件中也提供了Swiper组件,用于子组件滑动轮播显示,和前端的使用起来也是异曲同工,我们先看下基本的用法。
布局王 布局王
1个月前
Uniapp开发鸿蒙购物项目实战教程:实现首页轮播图
过去几天的文章中我们讲过了如何创建跨平台项目,如何进行基础的布局、如何实现自定义导航栏等等,通过这一系列的文章教程,我们最终要实现一个购物app,今天我们要做购物应用首页的轮播图部分。对于轮播图uniapp提供了相应的组件swiper,并且是支持鸿蒙应用的
布局王 布局王
2个月前
Uniapp开发鸿蒙购物项目教程之样式选择器
大家下午好,今天依然为大家带来鸿蒙跨平台开发教程的分享,我们本系列的教程最终要做一个购物应用,通过这个项目为大家分享uniapp开发鸿蒙应用从配置开发环境到应用打包上架的完成过程。昨天的文章实现了应用首页的轮播图,其中涉及到为轮播图设置样式,放一小段代码带
瘢痂协程
瘢痂协程
Lv1
故乡今夜思千里,霜鬓明朝又一年。
文章
3
粉丝
0
获赞
0