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 相关文章推荐
javascript showModalDialog 多层模态窗口实现页面提交及刷新的代码
Nov 28 Javascript
JavaScript 学习笔记(十六) js事件
Feb 01 Javascript
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
Nov 20 Javascript
THREE.JS入门教程(5)你应当知道的十件事
Jan 24 Javascript
深入解析JavaScript框架Backbone.js中的事件机制
Feb 14 Javascript
理解javascript对象继承
Apr 17 Javascript
Javascript之面向对象--方法
Dec 02 Javascript
js 作用域和变量详解
Feb 16 Javascript
Angular.js与node.js项目里用cookie校验账户登录详解
Feb 22 Javascript
Layui表格行工具事件与数据回填方法
Sep 13 Javascript
基于VSCode调试网页JavaScript代码过程详解
Jul 20 Javascript
JavaScript点击按钮生成4位随机验证码
Jan 28 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 使用post,get的一种简洁方式
2010/04/25 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(六)
2014/06/23 PHP
php获取数组元素中头一个数组元素值的实现方法
2014/12/20 PHP
使javascript也能包含文件
2006/10/26 Javascript
window.location和document.location的区别分析
2008/12/23 Javascript
js弹窗代码 可以指定弹出间隔
2010/07/03 Javascript
Javascript获取表单名称(name)的方法
2015/04/02 Javascript
JavaScript获取网页表单action属性的方法
2015/04/02 Javascript
浅谈Javascript数组索引
2015/07/29 Javascript
bootstrapValidator表单验证插件学习
2016/12/30 Javascript
利用node.js如何搭建一个简易的即时响应服务器
2017/05/28 Javascript
mac上node.js环境的安装测试
2017/07/03 Javascript
Canvas放置反弹效果随机图形(实例)
2017/08/17 Javascript
Angularjs按需查询实例代码
2017/10/30 Javascript
解决vue.js 数据渲染成功仍报错的问题
2018/08/25 Javascript
create-react-app安装出错问题解决方法
2018/09/04 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
微信小程序canvas动态时钟
2020/10/22 Javascript
[02:01]大师之路——DOTA2完美大师赛11月论剑上海
2017/11/06 DOTA
对python中矩阵相加函数sum()的使用详解
2019/01/28 Python
Python实现剪刀石头布小游戏(与电脑对战)
2019/12/31 Python
基于pycharm 项目和项目文件命名规则的介绍
2021/01/15 Python
使用豆瓣源来安装python中的第三方库方法
2021/01/26 Python
Canvas 文本转粒子效果的实现代码
2019/02/14 HTML / CSS
Schecker荷兰:狗狗用品和配件
2019/06/06 全球购物
钳工实习自我鉴定
2013/09/19 职场文书
应聘教师自荐信
2013/10/12 职场文书
给分销商的致歉信
2014/01/14 职场文书
协会周年庆活动方案
2014/08/26 职场文书
2014年个人教学工作总结
2014/12/09 职场文书
2015年三八妇女节活动总结
2015/02/06 职场文书
出纳岗位职责范本
2015/03/31 职场文书
音乐会主持人开场白
2015/05/28 职场文书
公司业务员管理制度
2015/08/05 职场文书
小学班主任工作随笔
2015/08/15 职场文书
vue封装数字翻牌器
2022/04/20 Vue.js