zoukankan      html  css  js  c++  java
  • 性能优化之节流、防抖

    1. 防抖:

    • 由于dom操作极其昂贵,所以尝试过多的dom操作有可能会将浏览器搞崩溃,比如onresize、onscroll这类事件操作;
    • 为了解决这个问题,引出防抖的概念(某些代码不可以在没有间断的情况下连续重复执行);
    • 方案:第一次调用函数创建一个定时器,在指定时间之后执行代码;在第二次调用时,清除掉前一次的定时器并重新设置一个;
    • 这种方案下,如果第一个定时器已经执行,这个操作就没意义;如果第一个没执行,则将其替换为新的定时器;目的是只有在执行函数的请求停止一段时间后才执行;
    • 适用于代码是周期执行的,但是你不能控制请求执行的速率;
    • 函数防抖让一个函数只有在你不断触发后停下来歇会才开始执行,中间你操作得太快它直接无视。
      // 函数防抖
      function debounce(method, context) {
          clearTimeout(method.tid);  // mthod是真实要执行的函数,context是执行的作用域(默认window)
          method.tid = setTimeout(function() {
              method.call(context)   // 确保方法在适当的环境中执行
          }, 100);
      }
      
      // onscroll时函数防抖
      function scrollFun() {
          var marginBot = 0;
          if (document.documentElement) {
              marginBot = document.documentElement.scrollHeight - (document.documentElement.scrollTop+document.body.scrollTop) - document.documentElement.clientHeight;
          } else {
              marginBot = document.body.scrollHeight - document.body.scrollTop - document.body.clientHeight;
          }
          if(marginBot <= 0) {
              // 滚动到底部加载数据操作
          }
      }
      window.onscroll = function() {
          debounce(scrollFun);
      }

    2. 节流

    • 如果我们不希望每次都是要事件结束后等待延迟时间后执行回调;
    • 我们可以先给定一个时间段duration,过了这个时间段以后我们执行相应的操作;如果没有过这个时间段,那么就按照函数节流的思路,开关定时器就ok。

    function throttle(method, delay, duration){
        var timer = null, stime = new Date();          // 记录下开始执行函数的时间
        return function() {
            var context = this, args = arguments,
            ctime = new Date();   // 记录下当前时间
            
            clearTimeout(timer);     // 函数节流里的思路
    
            // 记录下的两个时间相减再与duration进行比较
            if (ctime - stime >= duration) {
                method.apply(context, args);
                stime = ctime;
            }
        }
    }
    
    window.onresize = throttle(method, 50, 100);
    // 50ms的间隔内连续触发的调用,后一个调用会把前一个调用的等待处理掉,但每隔100ms至少执行一次

    3. 滚动实例区分下:

        normal:滚动会立即触发事件执行;

        throttle: 延迟100ms直到100ms以内没有事件触发之后执行,这样如果一直在操作,有可能一直不会触发事件发生;

        debounce:50ms的间隔内连续触发的调用,后一个调用会把前一个调用的等待处理掉,但每隔100ms至少执行一次。

    4. 滚动到目标节点:

    • 获取目标节点偏移量var len = $('target').offset().top或document.querySelector('target').offsetTop;
    • 滚动$('body').animate(scrollTop: len)或document.querySelector('body').scrollTop = len;
  • 相关阅读:
    线程 & 进程 & 协程
    redis入门
    插入排序
    java多线程(7)实现一个线程池
    java多线程(6)模拟排队叫号程序,4个线程都干活并且结果正确
    java多线程(5)模拟排队叫号程序,不能出现交替执行的结果
    java多线程(4)模拟排队叫号程序,不能出现交替执行的结果
    java多线程(3)其实本节和多线程无关,简单的模板设计模式
    java多线程(2)连续重启一个线程报错
    java多线程(1)
  • 原文地址:https://www.cnblogs.com/colima/p/7163057.html
Copyright © 2011-2022 走看看