Javascriptでウィンドウのリサイズやスクロールイベントの発生回数を抑える小技

Javascriptでウィンドウのリサイズやスクロールを検出して処理を実行することがあります。
そんな時に使う「window.onresize」や「window.onscroll」は何も対策をしないともの凄い数のイベントが発生してしまいます。

そこで、そんなイベント発生回数を抑える小技を紹介します。
スクロールイベントに重い処理を行おうと考えている方は一考の価値があると思います。


リサイズイベント「window.onresize」

ウィンドウのリサイズイベントである「window.onresize」はウィンドウのサイズが僅かに変化する度にイベントが発生します。
通常、リサイズ中に処理を実行することは稀であると思います。

そこで、ウィンドウサイズが “変化している間” は処理をスキップするようにすれば発生回数を抑えることができます。

この “変化している間” をどう検出するかですが、ここでは短い間隔でイベントが再度呼び出された場合として検出することとします。
従って、処理を setTimeout 関数で少し待ってから実行するようにして、この “待ち” の時間中に再度イベントが発生した時には待ち時間をリセットするようにしてやります。

上記のように処理させればウィンドウのリサイズしていない時間が一定時間以上になった場合にだけ処理が実行されることになります。

var _resizeEvent;  // タイマーのIDを保存する変数
window.onresize = function(){  // リサイズイベントが発生したら無名関数を呼び出す
  clearTimeout(_resizeEvent);  // 呼び出される度にsetTimeout関数を削除してリセットする
  _resizeEvent = setTimeout(function(){
      //
      // リサイズ後に行う処理
      //
  }, 200);  // 200msを待ち時間として設定
  // 待ち時間は長いほどイベント発生回数が減りますが、動作が遅れるので処理内容に応じて適宜調整して下さい
  // 処理の重さと反応性のバランスを取って快適なブラウジングができる時間を探して下さい
};

実際にリサイズでの処理が軽減されるか処理の実行回数を数えてみましょう。

対策しない場合 : 0 回
対策をした場合 : 0 回

スクロールイベント「window.onscroll」

スクロールイベントである「window.onscroll」はリサイズ同様に僅かにスクロールされるだけでイベントが発生します。
スクロールの場合はスクロール完了時だけ処理を行う、といった方法では処理頻度が不足することがあると思います。
なので、ある程度の (時間的な) 頻度では処理が実行されるようにしていきます。

一旦処理を setTimeout 関数で待たせて、待っている間は新たにスクロールイベントが発生しても処理をスキップさせていきます。

var _scrollEvent;  // タイマーのIDを保存する変数
window.onscroll = function(){  // スクロールイベントが発生したら無名関数を呼び出す
  if(!_scrollEvent){  // 処理も待ちが発生していなければタイマーをセットする
    _scrollEvent = setTimeout(function(){
        _scrollEvent = null;  // 処理に移ったらタイマーをnullにする
        //
        // スクロール中に行う処理
        //
    }, 200);  // 200msを待ち時間として設定
    // 待ち時間は長いほどイベント発生回数が減りますが、動作が遅れるので処理内容に応じて適宜調整して下さい
    // 処理の重さと反応性のバランスを取って快適なブラウジングができる時間を探して下さい
  }
};

実際にスクロールでの処理が軽減されるか処理の実行回数を数えてみましょう。

対策しない場合 : 0 回
対策をした場合 : 0 回

まとめ

以上、イベント発生回数が非常に多い「window.onresize」と「window.onscroll」の処理負荷を軽減する小技についてまとめました。

リサイズやスクロールするたびにカクカクするサイトはユーザから好まれないので、負荷が高い処理をこれらのイベントに組み込む場合はこのページを思い出して頂けると幸いです。

ご質問等あればコメントやお問い合わせからお願いします。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください