白話debounceとthrottle
4019 ワード
問題
開発中に頻度の高いイベントや連続的なイベントに遭遇し、パフォーマンスの最適化を行わないと、ページカートンなどの現象が発生する可能性があります.マウスイベント:mousemove(ドラッグ)/mouseover(スクライブ)/mouseWheel(ロールスクリーン) キーボードイベント:keypress(ajaxベースのユーザ名一意性チェック)/keyup(テキスト入力チェック、自動完了)/keydown(ゲーム中の射撃) windowのresize/scrollイベント(DOM要素動的位置決め) このような問題を解決するためによく使われる方法はthrottle(スロットル)とdebounce(ジッタ除去)である.throttle(スロットル)とdebounce(ジッタ除去)は、ある関数が一定時間に何回実行されるかを制御するためのソリューションであり、両者は似ていて異なる.
次に、両者の類似と違いを具体的に見てみましょう.
throttleとdebounceを知っています
throttleとdebounceの役割は,イベントの実行方法とタイミングを確認することであり,従来は両者の違いがよく分からず,両者を混同しやすい.
次は2つの簡単なシーンでdebounceとthrottleについて説明します.後でこの2つのシーンが混同されないと思います.
throttle実装
throttleとdebounceの最大の違いは、throttleにはバルブ値があり、バルブ値に達するとactionは必ず1回実行されます.
したがってthrottleの実装は、前のdebounceの実装に基づいて、バルブ値を追加するだけで、コードGithubリンクを追加することができます.
実際には、上記の実装は、パッケージを閉じて最初の時間を維持するだけで、心を簡素化することができます.
まとめ
前の紹介を通じて、debounceとthrottleに対して直観的な認識があるはずです. debounce:非常に頻繁にトリガーされるイベントを1回の実行 に統合する throttle:バルブ値を設定し、バルブ値内でトリガされたイベントを1回に統合して実行します.バルブ値に達すると、必ずイベント が実行する.
throttleとdebounceについて理解した後、一般的なシーンを見てみましょう.
debounceキーボードイベントについては、ユーザの入力が比較的頻繁である場合、debounceによりキーボードイベント処理 をマージすることができる. ajaxリクエストの場合、例えば、ページドロップダウンが一定の戻り値を超えるとajaxによって新しいページコンテンツが要求され、debounceによってajaxリクエストイベント がマージする.
throttleキーボードイベントでは、ユーザーが頻繁に入力しますが、一定時間(バルブ値)で処理関数を実行する必要がある場合はthrottleを使用します. 例えば、いくつかのウェブゲームのキーボードイベント マウスの移動とウィンドウのスクロールに対して、マウスの移動とウィンドウのスクロールは大量のイベントをもたらしますが、しばらくの間、ページの効果を見なければなりません. 例えばドラッグ可能なdivの場合、debounceを使用すると、divはドラッグが停止した後に一気にターゲット位置にジャンプする.この場合、throttle を使用する必要があります.
開発中に頻度の高いイベントや連続的なイベントに遭遇し、パフォーマンスの最適化を行わないと、ページカートンなどの現象が発生する可能性があります.
次に、両者の類似と違いを具体的に見てみましょう.
throttleとdebounceを知っています
throttleとdebounceの役割は,イベントの実行方法とタイミングを確認することであり,従来は両者の違いがよく分からず,両者を混同しやすい.
次は2つの簡単なシーンでdebounceとthrottleについて説明します.後でこの2つのシーンが混同されないと思います.
debounce
, , , , ;
, , ;
, , , , 。
所以debounce的作用是,当调用动作触发一段时间后,才会执行该动作,若在这段时间间隔内又调用此动作则将重新计算时间间隔。
throttle
, , , , ;
, , ;
, , , , 。
所以throttle的作用是,预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新的时间周期。
简单实现
有了上面的了解,就可以去实现简单debounce和throttle了。
debounce实现
首先来看看debounce的实现,根据前面对debounce的描述:
- debounce函数会通过闭包维护一个timer
- 当同一action在delay的时间间隔内再次触发,则清理timer,然后重新设置timer
可以在Chrome中运行下面的代码,看看debounce的效果,代码Github链接:
var debounce = function(action, delay) {
var timer = null;
return function() {
var self = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
action.apply(self, args)
}, delay);
}
}
// example
function resizeHandler() {
console.log("resize");
}
window.onresize = debounce(resizeHandler, 300);
throttle実装
throttleとdebounceの最大の違いは、throttleにはバルブ値があり、バルブ値に達するとactionは必ず1回実行されます.
したがってthrottleの実装は、前のdebounceの実装に基づいて、バルブ値を追加するだけで、コードGithubリンクを追加することができます.
var throttleV1 = function(action, delay, mustRunDelay) {
var timer = null,
startTime;
return function() {
var self = this,
args = arguments,
currTime = new Date();
clearTimeout(timer);
if(!startTime) {
startTime = currTime;
}
if(currTime - startTime >= mustRunDelay) {
action.apply(self, args);
startTime = currTime;
}
else {
timer = setTimeout(function() {
action.apply(self, args);
}, delay);
}
};
};
実際には、上記の実装は、パッケージを閉じて最初の時間を維持するだけで、心を簡素化することができます.
var throttleV2 = function(action, delay){
var statTime = 0;
return function() {
var currTime = +new Date();
if (currTime - statTime > delay) {
action.apply(this, arguments);
statTime = currTime ;
}
}
}
// example
function resizeHandler() {
console.log("resize");
}
window.onresize = throttleV2(resizeHandler, 300);
まとめ
前の紹介を通じて、debounceとthrottleに対して直観的な認識があるはずです.
throttleとdebounceについて理解した後、一般的なシーンを見てみましょう.
debounce
throttle