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

jQuery로 필요에 따라 로드하는 스크롤링 슬라이드(web 프론트엔드 성능 최적화)

서론

슬라이드 루프에 대해, 많은 사람들이 익숙하지 않을까요? 특히 jQuery 기반의 플러그인, 코드는 인터넷에서 많이 찾을 수 있지만, 정말로 자신의 요구사항에 맞는 것은 거의 없습니다. 따라서 저는 자신의 요구사항에 맞는, 널리 인터넷 사용자들에 의해 검증받을 수 있는 jQuery 슬라이드 루프를 만들고 싶습니다!

시각

왜 인터넷에서 다른 일부 슬라이드가 제 요구사항에 맞지 않는다고 말하는가요? 제 요구사항은 무엇인가요?

현재 인터넷에서 찾을 수 있는 많은 슬라이드 루프의 jQuery 플러그인의 방법은, 먼저 이미지와 링크의 HTML을 작성한 후, 순환하여 현재 슬라이드 이미지를 표시하기 위해 숨기고 표시하는 것입니다. 하지만 사용자의 관점에서는 항상 현재 한 장의 이미지만 보여집니다. 그렇다면 다른 몇 장의 숨겨진 이미지를 미리 로드하는 이유는 무엇인가요? 이는 시간과 노력을 낭비하는 것이 아닌가요? 따라서 제 첫 번째 요구사항은 필요에 따라 로드하는 것입니다.

우리는 일반적으로 루프 슬라이드를 홈페이지에 표시하지만, 홈페이지의 주요 내용은 최근 업데이트된 기사여야 합니다. 최소한 저는 이미지 표시 기능이 검색 엔진에 포함되어야 한다고 생각하지 않습니다. 따라서 제 두 번째 요구사항은 SEO와 일치해야 합니다.

구현

이 두 가지 요구 사항을 위해 DEMO를 하나 만들었습니다. 여러분은 이 DEMO의 소스 코드를 확인해 보세요. 차이점을 발견했습니다吗? 네, 이 DEMO의 HTML 소스 코드에서는 어떤 이미지도 볼 수 없으며, 모두 JS로 로드됩니다. 이는 스크래핑이 불가능하다는 것을 의미하며, 이미지가 전환될 때마다 현재 슬라이드 이미지가 하나씩 로드됩니다.

위 두 가지 요구사항을 위해 DEMO를 하나 만들었습니다. 이 DEMO의 소스 코드를 확인해 보세요. 차이점을 발견했습니다吗? 네, 이 DEMO의 HTML 소스 코드에서는 어떤 이미지도 볼 수 없으며, 모두 JS로 로드됩니다. 이는 스크래핑이 불가능하다는 것을 의미하며, 이미지가 전환될 때마다 현재 슬라이드 이미지가 하나씩 로드됩니다.

$(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="[#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
      }
    };
    //이미지가 완전히 로드된 후 천천히 로드하여 표시
    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>
      }
      //현재 상태 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();
})

필요에 따른 네트워크 요청 상황

 

그림에서 볼 수 있듯이 페이지가 로드될 때 자동으로 전환하거나 사용자가 클릭 전에 로드되는 slide 이미지는 한 장만 로드되어 페이지 로드량을 크게 절약합니다.

이점

같은 효과가 있지만, 구현 방법이 다르니까 이렇게 아깝지 않을까요? 이게 무엇이 이점인가요?

예를 들어, 최적화 전에 홈페이지에서 슬라이드 이미지가 전환되는 경우5장의 이미지를 로드해야 합니다.20K, 즉 최소한 홈페이지에 최소한100K의 이미지, 이렇게100K의 이미지를 모든 사용자가 볼 수 있을까요? 사용자가 볼지 않으면, 이것은 의미 없이 낭비되지 않을까요?100K의 로드 속도?

최적화된 경우, 첫 번째 페이지 로드 시에만 한 장의 이미지를 로드하면 됩니다.1K 근처의, 심지어 필요 없는 로딩 이미지도 사용자가 다음 이미지를 클릭하거나 타이머 설정에 도달할 때까지 로드하지 않고, 로드 시간을 크게 절약할 수 있습니다.1K?100K? 알고 계신다.

또한, 필요한 이미지를 JS로 로드하는 것은 JS를 지원하지 않는 모바일 브라우저에서도 로드 100K의 이미지는 전환할 수 없는 슬라이드 쇼에 큰 부담이 되며, 사용자 경험을 크게 저하할 수 있습니다.

좋아하는 것