Notice
Recent Posts
Recent Comments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 애니메이션
- Promise
- 모듈
- video
- animation
- Flex
- ES6
- event
- object
- ios
- 문자열
- 스크롤
- json
- async
- slice
- 비동기
- array
- IntersectionObserver
- 이벤트 루프
- ajax
- 클로저
- input
- scroll
- 이벤트
- 고차함수
- This
- Push
- 이벤트 위임
- dom
- 배열
Archives
- Today
- Total
FEDev Story
Swiper.js와 Ajax 호출을 이용한 동적 슬라이드 구현 본문
문제점
Swiper.js를 사용하여 슬라이드 적용시 좌우로 무한루프를 적용하기 위해 아래와 같이 옵션을 설정할 수 있다.
{loop:true]
문제는 무한 루프를 적용하기 위해 Swiper.js는 DOM을 좌우로 복사하게 된다.
즉 카테고리가 4개라면 다음과 같이 DOM을 복사한다.
카테고리 4개 * 3 = 12개의 DOM 생성
복사된 DOM 자체는 무겁지 않으나 로딩시 데이트를 한번에 불러와 복사된 DOM에 적용하는 과정에서 성능 저하를 가져오게 된다.
카테고리가 많아질 수록 성능이 더 저하될 수 밖에 없는 구조이다.
<section class="categoryReview">
<div class="swiper-container swiperSlide reviewTabs">
<ul class="swiper-wrapper tabs">
<li class="swiper-slide"><a nohref data-url="../data/reviewData_01.html" data-loaded=false>스킨케어</a></li>
<li class="swiper-slide"><a nohref data-url="../data/reviewData_02.html" data-loaded=false>메이크업</a></li>
<li class="swiper-slide"><a nohref data-url="../data/reviewData_03.html" data-loaded=false>바디/헤어/향수</a></li>
<li class="swiper-slide"><a nohref data-url="../data/reviewData_04.html" data-loaded=false>가방/지갑</a></li>
</ul>
</div>
<div class="swiper-container reviewContainer">
<div class="swiper-wrapper">
<div class="swiper-slide bestReviewArea">
</div>
<div class="swiper-slide bestReviewArea">
</div>
<div class="swiper-slide bestReviewArea">
</div>
<div class="swiper-slide bestReviewArea">
</div>
</div>
</div>
</section>
해결책
모든 데이터를 한번에 불러오지 않도록 Ajax를 적용하여 현재 활성화된 탭에 대해서만 데이터를 불러온 후 슬라이드 될 때마다 동적으로 데이터를 가져온다. 그리고 한번 불러온 데이터는 다시 호출하지 않는 방식으로 성능을 개선할 수 있다.
이때 한가지 문제점은 슬라이드시 Ajax를 호출하여 데이터를 가져오는 과정에서 어느정도의 지연현상이 발생한다.
이를 위해 $.when()을 사용하여 이전탭, 활성탭, 다음탭의 슬라이드 데이터를 미리 가져오면 지연현상없이 자연스럽게 슬라이드를 할 수 있다.
var swiperFn = swiperFn || {};
swiperFn.categorySwiperModule = (function(){
var reviewContainer, reviewTabs;
var swiperLoaded = false;
function initSwiper(){
reviewContainer = new Swiper('.reviewContainer', {
spaceBetween: 10,
loop: true,
loopedSlides: 4,
lazy : {
loadOnTransitionStart : true,
loadPrevNext : true
},
on: {
init: function(){
console.log('swiper initialized');
swiperLoaded = true
},
slideChangeTransitionEnd: function(swiper){
console.log('slide change');
var swiper = this;
var currentUrl, prevUrl, nextUrl;
var $activeReviewSlide = $(swiper.slides[swiper.activeIndex]);
var $prevReviewSlide = $(swiper.slides[swiper.activeIndex-1]);
var $nextReviewSlide = $(swiper.slides[swiper.activeIndex+1]);
if(reviewTabs !== undefined){
currentUrl = $('a', $(reviewTabs.slides[reviewTabs.activeIndex])).data('url');
prevUrl = $('a', $(reviewTabs.slides[reviewTabs.activeIndex-1])).data('url');
nextUrl = $('a', $(reviewTabs.slides[reviewTabs.activeIndex+1])).data('url');
if ($('ul', $activeReviewSlide).length === 0){
getData(currentUrl).done(function(data){
console.log('call current');
$activeReviewSlide.append(data);
});
}
if ($('ul', $prevReviewSlide).length === 0){
getData(prevUrl).done(function(data){
console.log('call prev');
$prevReviewSlide.append(data);
});
}
if ($('ul', $nextReviewSlide).length === 0){
getData(nextUrl).done(function(data){
console.log('call next');
$nextReviewSlide.append(data);
});
}
}
}
}
});
reviewTabs = new Swiper('.reviewTabs', {
spaceBetween: 10,
centeredSlides: false,
slidesPerView: 'auto',
touchRatio: 0.2,
slideToClickedSlide: true,
initialSlide: 0,
loop: true,
loopedSlides: 4,
slideActiveClass : 'active',
on: {
init: function(){
var currentUrl = $('a', this.slides[this.activeIndex]).data('url');
var prevUrl = $('a', this.slides[this.activeIndex-1]).data('url');
var nextUrl = $('a', this.slides[this.activeIndex+1]).data('url');
ajaxCall(currentUrl, prevUrl, nextUrl).done(function(currentData, prevData, nextData){
if(currentData[1] === 'success'){
$('.categoryReview .reviewContainer .swiper-slide-active').append(currentData[0]);
}
if(prevData[1] === 'success'){
$('.categoryReview .reviewContainer .swiper-slide-prev').append(prevData[0]);
}
if(nextData[1] === 'success'){
$('.categoryReview .reviewContainer .swiper-slide-next').append(nextData[0]);
}
});
}
}
});
reviewContainer.controller.control = reviewTabs;
reviewTabs.controller.control = reviewContainer;
}
function getData(url){
return $.get(url);
}
function ajaxCall(_currentUrl, _prevUrl, _nextUrl){
var def = $.Deferred();
$.when(getData(_currentUrl), getData(_prevUrl), getData(_nextUrl))
.done(function(data1, data2, data3){
def.resolve(data1, data2, data3);
})
return def.promise();
}
return {
init: function(){
initSwiper();
}
}
}());
swiperFn.categorySwiperModule.init();
참고문서 :
http://michaelsoriano.com/working-with-jquerys-ajax-promises-and-deferred-objects/
http://idangero.us/swiper/api/
'Web.Dev' 카테고리의 다른 글
[최적화] DOMContentLoaded, load, unload출처: (0) | 2019.06.17 |
---|---|
[최적화] 브라우저 렌더링 (0) | 2019.06.17 |
[스크랩] 스크롤을 감지하여 사이트의 헤더를 보이거나 숨기기 (0) | 2019.01.10 |
HTML 엔티티(entity) 이스케이프(escape), 이스케이핑(escaping) (0) | 2018.09.12 |
[HTML] 엔티티 코드(entity code) (0) | 2018.09.12 |
Comments