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 相关文章推荐
解决extjs grid 不随窗口大小自适应的改变问题
Jan 26 Javascript
jQuery设置和移除文本框默认值的方法
Mar 09 Javascript
简单实现兼容各大浏览器的js复制内容到剪切板
Sep 09 Javascript
JavaScript实现的背景自动变色代码
Oct 17 Javascript
javascript实现自动填写表单实例简析
Dec 02 Javascript
学习使用grunt来打包JavaScript和CSS程序的教程
Jan 04 Javascript
JavaScript重载函数实例剖析
May 13 Javascript
JavaScript中子对象访问父对象的方式详解
Sep 01 Javascript
JavaScript正则表达式实例详解
Oct 16 Javascript
vue 打包后的文件部署到express服务器上的方法
Aug 09 Javascript
NW.js 简介与使用方法
Feb 01 Javascript
JS实现基本的网页计算器功能示例
Jan 16 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
zf框架的数据库追踪器使用示例
2014/03/13 PHP
php将文件夹打包成zip文件的简单实现方法
2016/10/04 PHP
关于php几种字符串连接的效率比较(详解)
2017/02/22 PHP
Yii2.0多文件上传实例说明
2017/07/24 PHP
jquery单行文字向上滚动效果示例
2014/03/06 Javascript
浅谈js的setInterval事件
2014/12/05 Javascript
谈一谈jQuery核心架构设计
2016/03/28 Javascript
Bootstrap table分页问题汇总
2016/05/30 Javascript
js实现数字递增特效【仿支付宝我的财富】
2017/05/05 Javascript
微信小程序 wx.request方法的异步封装实例详解
2017/05/18 Javascript
vue2.0 移动端实现下拉刷新和上拉加载更多的示例
2018/04/23 Javascript
JavaScript中import用法总结
2019/01/20 Javascript
linux 下以二进制的方式安装 nodejs
2020/02/12 NodeJs
vue video和vue-video-player实现视频铺满教程
2020/10/30 Javascript
[02:28]DOTA2英雄基础教程 灰烬之灵
2013/12/19 DOTA
[02:43]DOTA2英雄基础教程 德鲁伊
2014/01/13 DOTA
[05:13]TI4 中国战队 机场出征!!
2014/07/07 DOTA
Python中模拟enum枚举类型的5种方法分享
2014/11/22 Python
利用python画一颗心的方法示例
2017/01/31 Python
python类的实例化问题解决
2019/08/31 Python
DJANGO-URL反向解析REVERSE实例讲解
2019/10/25 Python
如何基于python操作excel并获取内容
2019/12/24 Python
使用tensorflow实现VGG网络,训练mnist数据集方式
2020/05/26 Python
CSS3旋转——彩色扇子兼容firefox浏览器
2013/06/04 HTML / CSS
关于canvas.toDataURL 在iOS运行失败的问题解决
2020/09/16 HTML / CSS
Vans奥地利官方网站:美国原创极限运动潮牌
2018/09/30 全球购物
求职自荐书范文
2013/12/04 职场文书
会计专业个人求职信范文
2014/01/08 职场文书
《小蝌蚪找妈妈》教学反思
2014/02/21 职场文书
奥巴马胜选演讲稿
2014/05/15 职场文书
数据保密承诺书
2014/06/03 职场文书
三八妇女节标语
2014/10/09 职场文书
幼师小班个人总结
2015/02/12 职场文书
2015年读书月活动总结
2015/03/26 职场文书
解决redis sentinel 频繁主备切换的问题
2021/04/12 Redis
Python中re模块的元字符使用小结
2022/04/07 Python