2013-10-09 1 views
0

최근에 window.scroll을 사용하여 css3 애니메이션을 트리거하는 요소에 '활성'클래스를 추가하는 웹 사이트를 만들었습니다. 이 애니메이션은 때로는 불을 피우지 못했지만 대본의 모든 성능은 모두 매우 느 렸습니다. 오늘 나는 firefox parallax site 을보고 있었고 결코 '방아쇠'를 놓치지 않고 성능이 좋았다는 사실을 알았지 만 이러한 결과를 얻는 방법을 찾지 못했습니다.자바 스크립트 성능 - 작은 스크립트의 성능을 향상시키는 방법

내 코드는 순간 다음과 같습니다

...

$(window).scroll(function(){  
    if ($('.trigger:in-viewport:first.trigger5').length) 
    { 
     $('[rel=counter]').addClass('active'); 
     $('[rel=discover]').removeClass('active'); 
     $('[rel=follow]').removeClass('active'); 
     $('[rel=sync]').removeClass('active'); 
    } 

가 나는 느낌이 그 시간이 jQuery를에 소요되는

+7

속합니다 codereview.stackexchange.com –

+2

에 속함 스크롤 및 mousemove와 같은 빠른 실행 이벤트에서 DOM 쿼리를 수행합니다. 고전적인 실수. –

+4

'.scroll()'콜백 함수 밖의 변수에서'$()'쿼리를 캐쉬 해보십시오. 스크롤 이벤트가 발생하고 콜백 함수가 실행될 때마다 DOM이 * 5 * 번 쿼리됩니다. – ajp15243

답변

1

먼저하고 분명한 것은 : 주석처럼

var $window = $(window); 
var DOM = { 
    counter: $('[rel=counter]'), 
    discover: $('[rel=discover]'), 
    follow: $('[rel=follow]'), 
    sync: $('[rel=sync] ') 
}; 

function doThingsOnScroll() {  
    if ($('.trigger:in-viewport:first.trigger5').length) { 
     DOM.counter.addClass('active'); 
     DOM.discover.removeClass('active'); 
     DOM.follow.removeClass('active'); 
     DOM.sync.removeClass('active'); 
    } 
} 

$window.scroll(doThingsOnScroll); 

: 당신은 쿼리를 캐시해야합니다. DOM에 대한 조작은 매우 무겁습니다. 요소를 한 번 가져 와서 사용하십시오.

도움이 될 또 다른 기능은 밑줄 기능입니다. http://underscorejs.org/#throttle

var throttled = _.throttle(doThingsOnScroll, 100); 
$window.scroll(throttled); 

는 얼마 전에 폴 루이스는 HTML5ROCKS에 스크롤에 대한 기사를 썼다. 수정하기 전에 읽으십시오 : Scrolling Performance

EDIT : fixed :in-viewport. Bergi에게 감사드립니다.

+2

': in-viewport' 선택기를 활성화하는 플러그인이 무엇인지 모르겠지만 스크롤 이벤트에서 쿼리 할 가치가있는 유일한 동적 인 것으로 보입니다. 모든 jQuery 선택 항목이 정적 인 경우 doThingsOnScroll을 수행 할 필요가 없습니다. 스로틀 약 – Bergi

+0

. 그것은 함수 호출을 100ms 동안 캐시합니다, 맞습니까? –

+0

@Bergi,'[rel = xxx]'는 추가 j없이 동적 일 수 있습니까? ': in-viewport'와 일치합니다. –

0

jQuery를 뷰포트 플러그인의 사용 .. 셀렉터. 선택기를 먼저 실행하여 변수에 저장하면됩니다. 그런 다음 나중에 해당 변수를 사용하십시오. 예 :

var $firstTrigger = $('.trigger:in-viewport:first.trigger5'); 
var $counter = $('[rel=counter]'); 
var $discover = $('[rel=discover]'); 
var $follow = $('[rel=follow]'); 
var $sync = $('[rel=sync]'); 

$(window).scroll(function(){  
    if ($firstTrigger.length) 
    { 
     $counter.addClass('active'); 
     $discover.removeClass('active'); 
     $follow.removeClass('active'); 
     $sync.removeClass('active'); 
    } 
+0

'$ firstTrigger'는 매우 다른 선택자를 가지고 있습니다. – Bergi

+0

감사. 어떻게 엉망이 됐는지 확신 할 수 없습니다. – Pete

0

지금 dom-heavy 호출을 무시하면 scroll()의 신속한 실행 덕분에 전체 패턴이 매우 무겁습니다. 이것은 10FPS의 프레임 속도에 간다

function doScroll(){  
    if ($('.trigger:in-viewport:first.trigger5').length) 
    { 
     $('[rel=counter]').addClass('active'); 
     $('[rel=discover]').removeClass('active'); 
     $('[rel=follow]').removeClass('active'); 
     $('[rel=sync]').removeClass('active'); 
    } 
} 

$(window).scroll(function dome(){ 
    clearTimeout(dome.timer); 
    dome.timer=setTimeout(doScroll, 100); 
}) 

을하여 조정 주시기 :

우리는 esspecially 모바일 또는 다른 약한 장치, CPU에 큰 감소 만 종종 대신 항상의를 호출 할 수 있습니다 setTimeout 지속 기간을 변경합니다.

jQuery 선택기를 캐시하는 것이 도움이 될 수 있지만 scroll()을 너무 많이 실행하면 각 실행에 25 %를 절약하는 데 충분하지 않을 수 있지만 작업을 제거하면 추가 최적화와 관계없이 코드가 더 빠르게 실행됩니다. 만들어 질.