Javascript イベントポーリングの頻度を下げる
-
09-10-2019 - |
質問
JavaScript イベントポーリングの頻度を下げるにはどうすればよいですか?気になる出来事は、 サイズ変更時 そして オンスクロール. 。これらのイベントは、誰かがブラウザのサイズを変更したとき、または下にスクロールしたときに、それぞれ 1 秒あたり数十回トリガーされる可能性があります。これらのイベントは 500 ミリ秒に 1 回だけ発生するようにしたいので、イベント ハンドラーの最適化とメモリ リークの確認に何時間も費やす必要がなくなります。
解決
var resizeTimeout;
window.onresize = function() {
if (resizeTimeout) {
clearTimeout(resizeTimeout);
}
resizeTimeout = setTimeout(function() {
// Do it!
}, 500);
});
これは、をトリガーします setTimeout()
その人がサイズ変更を終えてから500ms 〜500ms。
onscroll
バージョンは非常に似ています:)
他のヒント
イベントが発射される頻度を実際に制御することはできません。最初のイベント発砲の時間を覚えているようなことをすることができます。その結果、最初のイベントから500ミリ秒以上であるかどうかを確認することができます。ハンドラー、それ以外の場合は、イベントHanlderを終了するだけです
ハンドラーの最初に、500ミリ秒が最後の500msから通過しているかどうかを確認し、そうでない場合は戻ってきてください。
これらのイベントが発砲するのを防ぐことはできません。彼らはいつもします。あなたがしたいのは、すぐにリッスンを止めてから、イベントを処理して繰り返しを避けることです。その後、ハンドラー全体がSetimeOutの後に再びセットアップされます。誰かがウィンドウを変更しない限り、これ以上再帰は起こりません。ここでは5000msを使用しています。コンソールで機能するのを見るのが簡単だからです。 Spazのようにサイズを変更しても、5秒ごとにFFコンソールに複数のスパムを表示することはありません。
(function staggerListen(){
window.onresize = function(){
window.onresize = false;
console.log('spam');
setTimeout(staggerListen,5000);
};
})()
ロジックを使用して、ハンドラーの火災がハンドラーとIFステートメント +検索を技術的に発射するたびに何かをするかどうかを決定します。それは重くなる可能性があります。
アンダースコアを確認してください デバウンス 働き
渡された関数の新しい額面バージョンを作成して返します。これは、最後に呼び出されてから待機ミリ秒が経過するまで実行されるまで延期します。入力が停止した後にのみ発生するはずの動作を実装するのに役立ちます。たとえば、マークダウンコメントのプレビューをレンダリングし、ウィンドウがサイズ変更を停止した後にレイアウトを再計算するなど。
例:
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
//...
}
これが役立つことを願っています。