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 相关文章推荐
脚本吧 - 幻宇工作室用到js,超强推荐share.js
Dec 23 Javascript
用js来获取上传的文件名纯粹是为了美化而用
Oct 23 Javascript
js实现获取焦点后光标在字符串后
Sep 17 Javascript
关于javascript的一些知识以及循环详解
Sep 12 Javascript
layer弹出层中H5播放器全屏出错的解决方法
Feb 21 Javascript
Angular 2父子组件之间共享服务通信的实现
Jul 04 Javascript
vue实现手机号码抽奖上下滚动动画示例
Oct 18 Javascript
vue引入js数字小键盘的实现代码
May 14 Javascript
react native 文字轮播的实现示例
Jul 27 Javascript
Angular8基础应用之表单及其验证
Aug 11 Javascript
详解Vue Cli浏览器兼容性实践
Jun 08 Javascript
微信小程序反编译的实现
Dec 10 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
学习php笔记 字符串处理
2010/10/19 PHP
linux下删除7天前日志的代码(php+shell)
2011/01/02 PHP
php HandlerSocket的使用
2011/05/02 PHP
深入了解 register_globals (附register_globals=off 网站打不开的解决方法)
2012/06/27 PHP
php 中文字符串首字母的获取函数分享
2013/11/04 PHP
PHP连接操作access数据库实例
2015/03/30 PHP
Yii2中OAuth扩展及QQ互联登录实现方法
2016/05/16 PHP
PHP单元测试框架PHPUnit用法详解
2019/01/23 PHP
JS TextArea字符串长度限制代码集合
2012/10/31 Javascript
javascript中的原型链深入理解
2014/02/24 Javascript
jQuery取id有.的值的方法
2014/05/21 Javascript
JavaScript导出Excel实例详解
2014/11/25 Javascript
node.js开机自启动脚本文件
2014/12/24 Javascript
jQuery及JS实现循环中暂停的方法
2015/02/02 Javascript
javascript表格隔行变色加鼠标移入移出及点击效果的方法
2015/04/10 Javascript
vue2.0 父组件给子组件传递数据的方法
2018/01/15 Javascript
vue.js做一个简单的编辑菜谱功能
2018/05/08 Javascript
vue中render函数的使用详解
2018/10/12 Javascript
vue配置接口域名方法总结
2019/05/12 Javascript
node.js事件轮询机制原理知识点
2019/12/22 Javascript
Vue项目vscode 安装eslint插件的方法(代码自动修复)
2020/04/15 Javascript
Vue 使用iframe引用html页面实现vue和html页面方法的调用操作
2020/11/16 Javascript
Python中利用sqrt()方法进行平方根计算的教程
2015/05/15 Python
Python三级菜单的实例
2017/09/13 Python
Python3中的json模块使用详解
2018/05/05 Python
pandas修改DataFrame列名的实现方法
2019/02/22 Python
python hough变换检测直线的实现方法
2019/07/12 Python
使用python处理题库表格并转化为word形式的实现
2020/04/14 Python
几道数据库的面试题或笔试题
2014/05/31 面试题
微信营销策划方案
2014/02/24 职场文书
幼儿园教师岗位职责
2014/03/17 职场文书
动漫设计与制作专业推荐信
2014/07/07 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
2014年教育教学工作总结
2014/11/13 职场文书
2016计算机专业毕业生自荐信
2016/01/28 职场文书
pytorch中的model=model.to(device)使用说明
2021/05/24 Python