jQuery按需加载轮播图(web前端性能优化)


Posted in Javascript onFebruary 17, 2017

引言

关于幻灯轮播图,想必大家都不陌生,尤其是基于 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 +'" rel="external nofollow" title="' + imgAlt + '" class="pic">' +
              '    <img src="' + imgSrc + '" alt="' + imgAlt + '" class="slide_thumb" />' +
              '  </a>' +
            '</li>',
        slideTextHtml = '<a href="' + imgUrl + '" rel="external nofollow"  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按需加载轮播图(web前端性能优化) 

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

优势

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

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

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

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

Javascript 相关文章推荐
css transform 3D幻灯片特效实现步骤解读
Mar 27 Javascript
js中的时间转换—毫秒转换成日期时间的示例代码
Jan 26 Javascript
javascript闭包传参和事件的循环绑定示例探讨
Apr 17 Javascript
JavaScript转换数据库DateTime字段类型方法
Jun 27 Javascript
基于Two.js实现星球环绕动画效果的示例
Nov 06 Javascript
浅谈node模块与npm包管理工具
Jan 03 Javascript
微信小程序实现多选框全选与取消全选功能示例
May 14 Javascript
vue cli3.0 引入eslint 结合vscode使用
May 27 Javascript
微信小程序保持session会话的方法
Mar 20 Javascript
Vue 基于 vuedraggable 实现选中、拖拽、排序效果
May 18 Javascript
JavaScript检测是否开启了控制台(F12调试工具)
Oct 02 Javascript
javascript数组includes、reduce的基本使用
Jul 02 Javascript
Vue.js中用webpack合并打包多个组件并实现按需加载
Feb 17 #Javascript
浅析JavaScript中var that=this
Feb 17 #Javascript
Bootstrap表格使用方法详解
Feb 17 #Javascript
BootStrap与Select2使用小结
Feb 17 #Javascript
解决给dom元素绑定click等事件无效问题的方法
Feb 17 #Javascript
Vue.js原理分析之observer模块详解
Feb 17 #Javascript
BootStrap的select2既可以查询又可以输入的实现代码
Feb 17 #Javascript
You might like
set_include_path在win和linux下的区别
2008/01/10 PHP
解析如何屏蔽php中的phpinfo()函数
2013/06/06 PHP
php实现从上传文件创建缩略图的方法
2015/04/02 PHP
弹出广告特效代码(一个IP只弹出一次)
2007/05/11 Javascript
javascript cookie解码函数(兼容ff)
2008/03/17 Javascript
JavaScript 事件参考手册
2008/12/24 Javascript
编写兼容IE和FireFox的脚本
2009/05/18 Javascript
ASP Json Parser修正版
2009/12/06 Javascript
初窥JQuery(二)事件机制(2)
2010/12/06 Javascript
简单选项卡 js和jquery制作方法分享
2014/02/26 Javascript
jQuery判断checkbox是否选中的3种方法
2014/08/12 Javascript
详解AngularJS中module模块的导入导出
2015/12/10 Javascript
vue.js-div滚动条隐藏但有滚动效果的实现方法
2018/03/03 Javascript
解决Vue中mounted钩子函数获取节点高度出错问题
2018/05/18 Javascript
在Vue中使用axios请求拦截的实现方法
2018/10/25 Javascript
Element输入框带历史查询记录的实现示例
2019/01/15 Javascript
tweenjs缓动算法的使用实例分析
2019/08/26 Javascript
node.js 基于 STMP 协议和 EWS 协议发送邮件
2021/02/14 Javascript
[55:25]VGJ.T vs Optic Supermajor小组赛D组 BO3 第三场 6.3
2018/06/04 DOTA
Python中使用插入排序算法的简单分析与代码示例
2016/05/04 Python
Python实现信用卡系统(支持购物、转账、存取钱)
2016/06/24 Python
深入理解NumPy简明教程---数组2
2016/12/17 Python
Python使用asyncio包处理并发详解
2017/09/09 Python
Python中xrange与yield的用法实例分析
2017/12/26 Python
对Python字符串中的换行符和制表符介绍
2018/05/03 Python
Python实现程序判断季节的代码示例
2019/01/28 Python
Django中ajax发送post请求 报403错误CSRF验证失败解决方案
2019/08/13 Python
使用python实现数组、链表、队列、栈的方法
2019/12/20 Python
Python Tkinter实例——模拟掷骰子
2020/10/24 Python
通信工程专业女生个人求职信
2013/09/21 职场文书
一名毕业生的自我鉴定
2013/12/04 职场文书
员工加薪申请报告
2015/05/15 职场文书
2016十一国庆节感言
2015/12/09 职场文书
践行三严三实心得体会(2016推荐篇)
2016/01/06 职场文书
幽默导游词应该怎么写?
2019/08/26 职场文书
Python 高级库15 个让新手爱不释手(推荐)
2021/05/15 Python