English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

jQuery lazy loading carousel (web front-end performance optimization)

Introduction

I'm sure everyone is not unfamiliar with slide carousels, especially those based on jQuery, with a myriad of plugins and code available online. However, there are almost none that truly meet one's needs. Therefore, I want to create a jQuery carousel that meets my own requirements and can stand the test of the vast majority of netizens!

Concept

Why do some other slide carousels online not meet my requirements? What are my requirements, after all?

The method commonly used in most jQuery plugins for online slide carousels is to first write the HTML for the images and links, and then control the hiding and showing to cycle through the current slide images. However, from the user's perspective, we only see one image at a time, so why load the other hidden images in advance? Isn't this a waste of time and effort? Therefore, my first requirement is to load on demand.

We usually place the carousel on the homepage for display, but the focus of the homepage should be on the latest updated articles, at least I don't think the image display function needs to be indexed by search engines, so my second requirement is SEO compliance.

Implementation

In response to the above two requirements, I made a DEMO, you might as well take a look at the source code of this DEMO, have you found the difference? Yes, in the HTML source code of this DEMO, you can't see any images and related information, all loaded by JS, that is to say, the crawler can't get it, and it loads the current slide image one by one as the image changes.

Here I just share my JS writing, please refer to the source code for HTML, I won't go into detail one by one, and the comments are also written very clearly.

$(function() {
  var WangeSlide = (function() {
    //Configuration
    var config = {
      //Carousel size
      width : 960,
      height : 350,
      //Whether to automatically switch
      autoSwitch : true,
      //Automatic switching interval time (milliseconds)
      interval : 6000,
      //Carousel image path
      picPath : 'http://www.dowebok.com/demo/2014/93/img/',
      //Carousel image information: image file name / image title / image link
      picInfo : [
        ['fullimage1.jpg', 'image1prompt','http://codepen.io/webstermobile/'],
        ['fullimage1.jpg', 'image2prompt','http://codepen.io/webstermobile/'],
        ['fullimage1.jpg', 'image3prompt','http://codepen.io/webstermobile/']
      ]
    };
    //Get image information
    /**
     * @param index Index value of the image
    **/
    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="[#0#]" class="pic">' +
              '    <img src="' + imgSrc + '" alt="[#0#]" class="slide_thumb" /'> +
              '  </a>' +
            </li>',
        slideTextHtml = '<a href="' + imgUrl + '" rel="external nofollow"  title="[#0#]">' + imgAlt+ </a>';
      return {
        imgAlt : imgAlt,
        imgUrl : imgUrl,
        imgHtml : imgHtml,
        slideTextHtml : slideTextHtml
      }
    };
    //Image fully loaded, then slowly load and display
    var fadeInImg = function(el, speed) {
      //console.log(el)
      el.find("img").load(function() {
        el.find("img").addClass("loaded")
        el.fadeIn(speed)
      });
    };
    //Image switching
    /**
     * @param index Index value of the image
     * @param triggerCurEl Current trigger node element
    **/
    var imgSwitch = function(index, triggerCurEl) {
      var slideId = 'slide_' + (index+1).toString(),
        slideIdEl = document.getElementById(slideId);
      if (slideIdEl) {
        //If there is already a corresponding element, display the existing element
        var panelLi = $('#panel ul li');
        panelLi.hide();
        $(slideIdEl).fadeIn('slow');
      } else {
        //If there is no corresponding element, inject the element
        $(getImgInfo(index).imgHtml).appendTo($('#panel ul'));
        var panelLi = $('#panel ul li');
        panelLi.hide();
        //Load display image
        fadeInImg($("#" +slideId), 'slow');
      }
      //Get the alt text of the image as display information
      $('#slide_text').html(getImgInfo(index).slideTextHtml);
      //Current state cur
      $('#trigger ul li').removeClass('cur');
      triggerCurEl.addClass('cur');
    };
    //Carousel
    var slide = function() {
      //Set carousel size
      $('#panel').css({
        'width' : config.width + 'px',
        'height' : config.height + "px"
      });
      var result = getImgInfo(0).imgHtml
      //Initialize the carousel, load only the first image information
      $('#panel ul').html($(result));
      //Load display image
      fadeInImg($('#slide_1), 500);
      //Inject background layer + Trigger container + Carousel text container
      var slideBg = '<div id="slide_bg"></div>',
        trigger = '<div id="trigger"></div>',
        slideText = '<div id="slide_text"></div>;
      $('#panel').after(slideBg + trigger + slideText);
      //Get the alt text of the image as display information
      $('#slide_text').html(getImgInfo(0).slideTextHtml);
      //Inject trigger node
      var triggerUl = $('<ul></ul>
      triggerUl.appendTo($('#trigger'));
      for (var i=0, j=config.picInfo; i<j.length; i++) {
        $('<li>') + (i+1).toString() +</li>
      }
      //Current state cur
      $('#trigger ul li').eq(0).addClass('cur');
      //Click to trigger the node
      $("#trigger ul li").click(function(){
        var index = $("#trigger ul li").index($(this))
        //console.log(index)
        imgSwitch(index,$(this))
      }
      //Stop switching when the mouse hovers
      var goSwitch = true;
      $('#panel').hover(
        function() {goSwitch = false},
        function() {goSwitch = true}
      );
      //Automatic Switching
      if (config.autoSwitch) {
        setInterval(function() {
          if (goSwitch) {
            //Determine the current cur index value
            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 {
      //Initialization
      init : function() {
        slide();
      }
    }
  })();
  WangeSlide.init();
}

On-demand loading network request situation

 

As can be seen from the figure, only one slide image is loaded when the page is loaded automatically or before the user clicks to switch, which greatly saves the page loading volume.

Advantages

The same effect, just different implementation methods? Isn't it a pain? What are the advantages?

For example, before optimization, suppose the homepage has幻灯图片5images, with an average of2OK, that is to say, your homepage at least needs to load10OK image, and this10Can you guarantee that every user will see the OK image? If the user does not see it, isn't it a waste of this10How fast is the loading speed of OK?

After optimization, only one image needs to be loaded when the homepage is loaded for the first time,1Around K, even if it is optional loading image, it will only load the next image when the user clicks on the next one or reaches the timer setting, which greatly saves the loading time.1K?10OK? You know what I mean.

Additionally, there is also an advantage to loading the required images with JS, that is, on some mobile browsers that do not support JS, loading 10The image for the unchangeable carousel is a great burden, and it will also greatly reduce the user experience.

You may also like