JavaScriptのイベントポーリングの頻度をどのように低くしますか?私が心配しているイベントは、onResizeとonScrollです。これらのイベントは、誰かがブラウザのサイズを変更したり、スクロールしたりすると、毎秒数十回トリガされます。これらのイベントは500ミリ秒ごとに1回しか発生しないようにしたいので、イベントハンドラを最適化してメモリをリークさせないように時間を費やす必要はありません。Javascriptイベントポーリングの頻度を低くする
答えて
var resizeTimeout;
window.onresize = function() {
if (resizeTimeout) {
clearTimeout(resizeTimeout);
}
resizeTimeout = setTimeout(function() {
// Do it!
}, 500);
});
人物のサイズ変更が完了してから、setTimeout()
機能がトリガーされます。
onscroll
バージョンは、あなたが本当にそれはだかどうかをチェック各後件1に、最初のイベントの発火の時間を覚えているようにイベントが発生するが、あなたが何かを行うことができますどのように頻繁に制御することはできません:)
非常に似ています最初のものから500ミリ秒以上が経過した場合 - イベントハンドラを続行します。それ以外の場合はイベントハンドラを終了します
+1この答えは、これはおそらくOPが望んでいるものです。ただし、最後のサイズ変更イベントを処理するには、追加のロジックが必要です。 – casablanca
私は、タイマーのソリューションが最後のサイズ変更イベントを処理すると思うので、実際のソリューションは2つの組み合わせになります – Andrey
ハンドラの開始時に、最後のものから500msが経過したかどうかを確認し、そうでなければ返す。
これらのイベントが発生するのを防ぐことはできません。彼らはいつもします。あなたがしたいことは、直ちに聞いてはいけないし、繰り返しを避けるためにイベントを処理することです。その後、setTimeoutの後にハンドラ全体が再び設定されます。誰かがウィンドウのサイズを変更しない限り、これ以上の再帰は起こりません。私はここで5000ミリメートルを使用しているので、コンソールで作業するのが簡単です。 spazのようにサイズを変更しても、5秒ごとにFFコンソールに複数のスパムが表示されるべきではありません。何にハンドラ火災はまだ技術的にハンドラとAN if文+検索を発射するたびに行うかどうかを判断するためのロジックを使用し
(function staggerListen(){
window.onresize = function(){
window.onresize = false;
console.log('spam');
setTimeout(staggerListen,5000);
};
})()
。それは重くなることがあります。
うわー。私は、リスナーのコールバックを動的に追加/削除するためのオーバヘッドが何であるか分かりませんが、とにかく難しいのは+1です。 :) – Phrogz
アンダースコアdebounce機能をチェックし
後のミリ秒は、それが呼び出された最後の時間から経過した待つまで、その実行を延期する渡された関数の新しいデバウンスバージョンを作成し、返します。入力の到着が停止した後にのみ実行されるべき動作を実装するのに役立ちます。たとえば、Markdownコメントのプレビューのレンダリング、ウィンドウのサイズ変更が停止した後のレイアウトの再計算などがあります。
例:
window.onscroll = _.debounce(
function() {
// do something
}, 500, false
);
私は受け入れ答えのようにそれを作るために使用されるが、問題はそれだけで指定されたタイムアウト後にトリガ、です。すぐにサイズ変更を処理するソリューションが必要でした。私がやったことがここにあります。
var _resize_is_busy = false;
var _resize_scheduled = false;
var _resize_precision = 100;
// This register for window resize events. No need to change anything.
$(window).resize(function() {
if (!_resize_is_busy) {
// call the scheduler who will do the work and set a timer to
// check of other resizes occured within a certain period of time
_resize_scheduler();
}
else {
// the resizer is busy, i.e. a resize have been handled a little
// time ago and then the scheduler is waiting some time before
// handling any other resize. This flag tells the scheduler that
// a resize event have been receive while he was sleeping.
_resize_scheduled = true;
}
});
// This is the scheduler. No need to change anything.
var _resize_scheduler = function() {
_resize_is_busy = true;
_resize_scheduled = false;
setTimeout(function() {
_resize_is_busy = false;
if (_resize_scheduled)
_handle_resize();
}, _resize_precision);
_handle_resize();
}
var _handle_resize = function() {
console.log('DOING ACTUAL RESIZE');
// do the work here
//...
}
これが役立ちます。
この1つは500 msごとに発火しません。停止/ポーズリサイズした後には500 msだけ発火します – Andrey
+1は私にそれを打ちます。 'resizeTimeout'のチェックは最初のラウンドで'未定義 'になるので、忘れないでください。 – casablanca
@Andrey:良い点 - 私はそれを見落としました。 – casablanca