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 相关文章推荐
jquery focus(fn),blur(fn)方法实例代码
Dec 16 Javascript
从面试题学习Javascript 面向对象(创建对象)
Mar 30 Javascript
JavaScript 学习笔记之一jQuery写法图片等比缩放以及预加载
Jun 28 Javascript
javascript 循环调用示例介绍
Nov 20 Javascript
B/S模式项目中常用的javascript汇总
Dec 17 Javascript
Javascript中实现String.startsWith和endsWith方法
Jun 10 Javascript
JavaScript的代码编写格式规范指南
Dec 07 Javascript
thinkjs之页面跳转同步异步操作
Feb 05 Javascript
JavaScript简单计算人的年龄示例
Apr 15 Javascript
详解如何在你的Vue项目配置vux
Jun 04 Javascript
security.js实现的RSA加密功能示例
Jun 06 Javascript
jQuery实现手风琴特效
Jan 11 jQuery
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
php下实现在指定目录搜索指定类型文件的函数
2008/10/03 PHP
php知道与问问的采集插件代码
2010/10/12 PHP
PHP 命令行工具 shell_exec, exec, passthru, system详细使用介绍
2011/09/11 PHP
php微信公众平台示例代码分析(二)
2016/12/06 PHP
phpMyAdmin无法登陆的解决方法
2017/04/27 PHP
Thinkphp 空操作、空控制器、命名空间(详解)
2017/05/05 PHP
PHP7引入的&quot;??&quot;和&quot;?:&quot;的区别讲解
2019/04/08 PHP
Laravel 手动开关 Eloquent 修改器的操作方法
2019/12/30 PHP
FireFox JavaScript全局Event对象
2009/06/14 Javascript
js 实现 input type=&quot;file&quot; 文件上传示例代码
2013/08/07 Javascript
js实现获取焦点后光标在字符串后
2014/09/17 Javascript
jQuery仿Flash上下翻动的中英文导航菜单实例
2015/03/10 Javascript
jQuery Ajax 实例代码 ($.ajax、$.post、$.get)
2016/04/29 Javascript
浅谈jquery的html方法里包含特殊字符的处理
2016/11/30 Javascript
JavaScript正则表达式小结(test|match|search|replace|split|exec)
2016/12/08 Javascript
基于JavaScript实现随机颜色输入框
2016/12/10 Javascript
AngularJS使用angular.bootstrap完成模块手动加载的方法分析
2017/01/19 Javascript
详解Angualr 组件间通信
2017/01/21 Javascript
JavaScript你不知道的一些数组方法
2017/08/18 Javascript
nodejs Assert中equal(),strictEqual(),deepEqual(),strictDeepEqual()比较
2017/09/18 NodeJs
vue2.0.js的多级联动选择器实现方法
2018/02/09 Javascript
vue-router重定向和路由别名的使用讲解
2019/01/19 Javascript
Vuex的actions属性的具体使用
2019/04/14 Javascript
微信小程序实现折线图的示例代码
2019/06/07 Javascript
微信小程序服务器日期格式化问题
2020/01/07 Javascript
uniapp微信小程序实现一个页面多个倒计时
2020/11/01 Javascript
深入Python解释器理解Python中的字节码
2015/04/01 Python
Python实现压缩与解压gzip大文件的方法
2016/09/18 Python
Python装饰器模式定义与用法分析
2018/08/06 Python
对web.py设置favicon.ico的方法详解
2018/12/04 Python
python利用selenium进行浏览器爬虫
2019/04/25 Python
HTML5页面直接调用百度地图API获取当前位置直接导航目的地的实现代码
2018/03/02 HTML / CSS
意大利比基尼品牌:MISS BIKINI
2019/11/02 全球购物
List、Map、Set三个接口,存取元素时,各有什么特点?
2015/09/27 面试题
关爱留守儿童标语
2014/06/18 职场文书
javaScript Array api梳理
2021/03/31 Javascript