throttle/debounce:cpuの減圧(フロントエンドパフォーマンス最適化)
12243 ワード
throttleとdebounceとは?
日语翻译:throttle绞死debounceデブレーブ
私たちの習慣を理解すると、節流に訳されます.
では、どんなシーンで使う必要がありますか?
シーン1:onresize,onscroll,onmousemove
シーン2:input,autocomplete
何もしないと、ブラウザはバインドされたイベントを頻繁に呼び出し、コンピュータの構成が低いとヒステリシスを感じます.つまり、アプリケーションのパフォーマンスが悪いです.
エントリーレベルの書き方:——ドラッグするとfireに登録されたイベント
function onResize(){ console.log('log'); }; window.addEventListener('resize',onResize,false)
進級の書き方:——静かになったらまた呼び出します.
ここで質問があります.変数timerを導入しました.それは実際にonResizeに属していますが、onResieには入れません.このように写実するのはあまりにも醜いので,方法を考えなければならない.
この変数をonResizeのプロパティに登録すると、次のようになります.
挿入文:この方法はproxyで役に立つ.domに登録されているイベントを削除するには、一致を指す必要があることはよく知られていますが、このproxyは役に立ちます.i.e、ただの栗!
再進階級の書き方:——パッケージ
ネット上では「オブジェクト向け、カプセル化、継承......」と叫んでいますが、カプセル化しないと、プロセスに向かって噴き出してしまうのではないでしょうか.
上では,実際には基礎的な関数スロットルを実現した.しかし、私たちは毎回同じ論理を書くことはできません.だから抽象的な共通関数でこのことをして、具体的にはこのように実現することができます.
jqueryはこのようにして、googleは$を検索することができます.throttle、でもどうして私はソースコードの中で探していませんか??
underscore.jsは、次のように実現されます.
呼び出し:
function calculateLayout(){ console.log('resize'); };
//直ちに実行するには、パラメータtrue_を入力.debounce(calculateLayout, 2000,true); var lazyLayout = _.debounce(calculateLayout, 2000); $(window).resize(lazyLayout);
baidu Tangram
見てないみたい??
では、簡単なパッケージを実現します.そんなに複雑で、理解しやすいバージョンは必要ありません.
詳細については、次の場所を参照してください.
1. http://remysharp.com/2010/07/21/throttling-function-calls/
2. http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/
3. http://www.css88.com/archives/5256#more-5256
4. http://www.alloyteam.com/2012/11/javascript-throttle/
日语翻译:throttle绞死debounceデブレーブ
私たちの習慣を理解すると、節流に訳されます.
では、どんなシーンで使う必要がありますか?
シーン1:onresize,onscroll,onmousemove
シーン2:input,autocomplete
何もしないと、ブラウザはバインドされたイベントを頻繁に呼び出し、コンピュータの構成が低いとヒステリシスを感じます.つまり、アプリケーションのパフォーマンスが悪いです.
エントリーレベルの書き方:——ドラッグするとfireに登録されたイベント
function onResize(){ console.log('log'); }; window.addEventListener('resize',onResize,false)
進級の書き方:——静かになったらまた呼び出します.
var timer = null; function onResize(){ clearTimeout(timer); timer = setTimeout(function(){ console.log('log'); },200); }; window.addEventListener('resize',onResize,false)
ここで質問があります.変数timerを導入しました.それは実際にonResizeに属していますが、onResieには入れません.このように写実するのはあまりにも醜いので,方法を考えなければならない.
この変数をonResizeのプロパティに登録すると、次のようになります.
function onResize(){ clearTimeout(onResize.timer); //this is difference onResize.timer = setTimeout(function(){ console.log('log'); },200); }; window.addEventListener('resize',onResize,false)
挿入文:この方法はproxyで役に立つ.domに登録されているイベントを削除するには、一致を指す必要があることはよく知られていますが、このproxyは役に立ちます.i.e、ただの栗!
Contextmenu.prototype = { proxy: function(fn){ if(!fn._contextmenu_proxy){ fn._contextmenu_proxy = $.proxy(fn, this); } return fn._contextmenu_proxy; }, init:function(dialModel,dialView){ var me = this; $document.on('contextmenu',me.proxy(me.onContextMenu)); } }
再進階級の書き方:——パッケージ
ネット上では「オブジェクト向け、カプセル化、継承......」と叫んでいますが、カプセル化しないと、プロセスに向かって噴き出してしまうのではないでしょうか.
上では,実際には基礎的な関数スロットルを実現した.しかし、私たちは毎回同じ論理を書くことはできません.だから抽象的な共通関数でこのことをして、具体的にはこのように実現することができます.
jqueryはこのようにして、googleは$を検索することができます.throttle、でもどうして私はソースコードの中で探していませんか??
underscore.jsは、次のように実現されます.
_.throttle = function(func, wait, options) { var context, args, result; var timeout = null; var previous = 0; options || (options = {}); var later = function() { previous = options.leading === false ? 0 : new Date; timeout = null; result = func.apply(context, args); }; return function() { var now = new Date; if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; }; // Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) { var timeout, args, context, timestamp, result; return function() { context = this; args = arguments; timestamp = new Date(); var later = function() { var last = (new Date()) - timestamp; if (last < wait) { timeout = setTimeout(later, wait - last); } else { timeout = null; if (!immediate) result = func.apply(context, args); } }; var callNow = immediate && !timeout; if (!timeout) { timeout = setTimeout(later, wait); } if (callNow) result = func.apply(context, args); return result; }; };
呼び出し:
function updatePosition(){ //console.log('s');
};
// , , _.throttle(updatePosition, 500,{leading:false});
// , , _.throttle(updatePosition, 500,{trailing:false});
var throttled = _.throttle(updatePosition, 500);
$(window).scroll(throttled);
//debonce——debonce , : , 。 , , , // , ,
function calculateLayout(){ console.log('resize'); };
//直ちに実行するには、パラメータtrue_を入力.debounce(calculateLayout, 2000,true); var lazyLayout = _.debounce(calculateLayout, 2000); $(window).resize(lazyLayout);
baidu Tangram
見てないみたい??
では、簡単なパッケージを実現します.そんなに複雑で、理解しやすいバージョンは必要ありません.
/* *author@http://wuya1234.github.io
* : 1. , setTimeout 2. , : 200 */
function throttle(fn,delay,mustRun){ var timer, t_start, previous; return function(){ var arg = arguments, scope = this; var now = +new Date; var defer = function(){ previous = now; fn.call(scope,arg); }; var diff = now - previous - delay; if(diff <= 0){ clearTimeout(timer); timeout = timer; previous = now; fn.call(scope,arg); }else{ timer = setTimeout(fn.call(scope,arg),diff); } }; }; function onResize(){ clearTimeout(onResize.timer); onResize.timer = setTimeout(function(){ console.log('log'); },200); }; window.addEventListener('resize',throttle(onResize),false);
詳細については、次の場所を参照してください.
1. http://remysharp.com/2010/07/21/throttling-function-calls/
2. http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/
3. http://www.css88.com/archives/5256#more-5256
4. http://www.alloyteam.com/2012/11/javascript-throttle/