再談給onScroll減壓

一直覺得setInterval給onscroll減壓這個辦法,定期去判斷瀏覽器是否觸發了滾動事件還是很挫的,近來在一個項目中突發奇想,讓我找到了更好的方法。就是onscroll的時候,判斷一下當前時間,詳細看代碼

var prevTime = + new Date;
window.onscroll = function() {
    var now = + new Date;
    //當前時間超過開始時間 200毫秒 則執行
    if ( now - prevTime > 200 ) {
        prevTime = now;
        scrollHandle();
    }
}



那我知道的方法有3個了


setTimeout

var timeout;
window.onscroll = function() {
    clearTimeout( timeout );
    timeout = setTimeout(function() {
        scrollHandle();
    }, 200);
}



setInterval

var changed = false;
window.onscroll = function() {
    changed = true;
}
setInterval( function() {
    if ( changed === true ) {
        scrollHandle();
        changed = false;
    }
} , 200);



time

var prevTime = + new Date;
window.onscroll = function() {
    var now = + new Date;
    //當前時間超過開始時間 200毫秒 則執行
    if ( now - prevTime > 200 ) {
        prevTime = now;
        scrollHandle();
    }
}



現在好好總結一下,也好好測試一下它們的效率。
我的想法是用chrome中的timeline,檢測每個方法在一個5秒滾動事件中的性能損耗,由於人工操作不能保障滾動時長,所以寫一個點擊事件去啓動一個setInterval不斷改變滾動條。


測試代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<button id="btn">test</button>
<div style="height:20000px;"></div>
<script>
var _window = window,
    _document = document,
    dElem = _document.documentElement,
    body = _document.body,
    interval,
    i = 0;

function getScrollTop() {
    return _window.pageYOffset 
                || 
                dElem.scrollTop 
                || 
                body.scrollTop
                ;
}
function test() {
    var now;
    if ( !interval ) {
        now = + new Date;
        interval = setInterval(function() {
            //5秒後停止
            if ( new Date - now > 5000 ) {
                clearInterval( interval );
                interval = null;
            } else {
                _window.scroll( 0, getScrollTop() + 5 );
            }
        }, 20);
    }   
}
function scrollHandle() {
    console.log( ++i );
}

_document.getElementById( 'btn' ).onclick = function() {
    test();
}


//setTimeout start
/*
var timeout;
_window.onscroll = function() {
    clearTimeout( timeout );
    timeout = setTimeout(function() {
        scrollHandle();
    }, 200);
}*/
//setTimeout end

//setInterval start
/*
var changed = false;
_window.onscroll = function() {
    changed = true;
}
setInterval( function() {
    if ( changed === true ) {
        scrollHandle();
        changed = false;
    }
} , 200);
*/
//setInterval end

//time start
var prevTime = + new Date;
_window.onscroll = function() {
    var now = + new Date;
    //當前時間超過開始時間 200毫秒 則執行
    if ( now - prevTime > 200 ) {
        prevTime = now;
        scrollHandle();
    }
}
//time end

</script>   
</body>
</html>



測試方法:
1. 打開chrome調試工具
2. 切換到timeline頻道
3. timeline頻道,點擊“record”按鈕
4. 頁面中點擊“test”按鈕,觸發滾動條動畫
5. 動畫停止後,timeline頻道,再次點擊“record”按鈕,停止記錄
6. 查看記錄數據



測試結果:
setTimeout
這裏寫圖片描述


setInterval
這裏寫圖片描述


time
這裏寫圖片描述


彙總
這裏寫圖片描述


總結
setTimeout 是最慢的,原因也很簡單,頻繁setTimeout及clearTimeout,也由於這個原因,得等到滾動事件停止才能執行回調。setInterval性能不錯,但對比time方法,它的定期檢查機制顯得太浪費了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章