JSでのブレ止めとスロットル


サマリ


ジッタ防止とスロットルはフロントエンド最適化の一部であり、過剰な要求を防止することができる.プロジェクトを始めたばかりの頃はまだ意識していませんでしたが、企業レベルの開発や大きなプロジェクト開発になったときは、ブレ防止や節流を考えなければなりません.詳細はjs:ブレ防止とスロットル

ブレ止め


ジッタ防止は,ある関数(要求)をユーザが操作を終了した所定時間後に実行させることをどのように理解するかである.
フォーム入力時などのシーンを適用するには、通常、空でないチェックが必要です.ジッタがない場合、ユーザーは文字を入力するたびに空でないチェックを実行します.ジッタを防止した後、ユーザは入力を停止してから数秒後に非空チェックを行うことができ、これにより関数またはインタフェース呼び出しの回数を節約し、パフォーマンスを向上させることができる.
コード#コード#

    /*   :                 
    *  fn       ,delay        
    *  return              
    */
    var debounce = function (fn, delay) {
        //     timer
        let timer = null;
        return function () {
            //    ‘this’   ‘arguments’            
            let context = this;
            let args = arguments;

            clearTimeout(timer);
            timer = setTimeout(function () {
                fn.apply(context, args);
            }, delay);
        }
    };
    function ajax(){
        console.log("  ajax  /    ,        ")
    };
    $("#input").on("input",debounce(ajax,1000));


コードから分かるように、ジッタ防止の実質はタイマーを維持することであり、高周波イベントがトリガーされるとタイマーを常にゼロにし、高周波イベントが停止した所定時間後にのみ関数をトリガーする.

しぼり


1つの関数が所定の時間に1回しか実行できないことをどのように理解しますか.
アプリケーションシーンは、例えば、ページが無限にロードされているシーンでは、ユーザーがページをスクロールする操作を停止したときにデータを要求するのではなく、一定の時間ごとに要求を送信します.
コードの2つの方法はそれぞれタイムスタンプとタイマーです
  • タイムスタンプ:高周波イベントがトリガーされると、最初はすぐに実行されるはずです(イベントバインド関数と実際のトリガーイベントの間隔がdelayより大きい場合)、その後どのように頻繁にイベントをトリガーしてもdelay秒ごとに実行されます.最後のイベントのトリガが完了すると、イベントは
  • に実行されません.
  • タイマ:イベントが最初にトリガーされると、関数はすぐに実行されず、delay秒後に実行されます.その後、イベントが連続的にトリガーされ、delay秒ごとに実行されます.最後にトリガを停止すると、タイマのdelayが遅延するため、関数も1回実行される可能性があります.

  • タイムスタンプとタイマーを組み合わせて、イベントトリガを完了するとすぐに実行され、トリガが完了すると一度のスロットル関数も実行されます.
    var throttle = function(func,delay){
        var timer = null;
        var startTime = Date.now();
    
        return function(){
            var curTime = Date.now();
            var remaining = delay-(curTime-startTime);
            var context = this;
            var args = arguments;
    
            clearTimeout(timer);
            if(remaining<=0){
                func.apply(context,args);
                startTime = Date.now();
            }else{
                timer = setTimeout(func,remaining);
            }
        }
    }
    

    各delay時間ごとに必ず1回関数を実行する必要があるため、スロットル関数内部で開始時間、現在時間、delayを用いてremainingを計算し、remaining<=0の場合はその実行関数を表し、まだ時間になっていない場合はremaining時間に設定してからトリガーする.もちろんremainingの間に再びイベントが発生すると、現在のタイマがキャンセルされ、remainingが再計算されて現在の状態が判断されます.