性能优化

优化高频事件:onscroll oninput resize onkeyup keydow降低代码执行率
scroll和resize会导致页面不断的重新渲染,如果绑定的回调函数中大量操作dom也会出现页面卡顿

节流

控制流量,保证一定之间内,核心代码只执行一次
场景

  1. scroll 事件,每隔一秒计算一次位置信息等
  2. 浏览器播放事件,每个一秒计算一次进度信息等
  3. input 框实时搜索并发送请求展示下拉列表,没隔一秒发送一次请求 (也可做防抖)

    1. function throttle(fn, delay) {
    2. var timer;
    3. return function () {
    4. var _this = this;
    5. var args = arguments;
    6. if (timer) {
    7. return;
    8. }
    9. timer = setTimeout(function () {
    10. fn.apply(_this, args);
    11. timer = null; // 在delay后执行完fn之后清空timer,此时timer为假,throttle触发可以进入计时器
    12. }, delay)
    13. }
    14. }

    防抖

    一段时间结束之后才触发一次事件,如果这一段时间未结束在此触发事件,就会重新计算时间
    比如:在电梯中门快要关了,突然有人上来了,一段时间没人按电梯,则电梯关门往目的地楼层运行
    场景:

  4. 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖

  5. 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖
  6. 文本编辑器实时保存,当无任何更改操作一秒后进行保存 ```javascript // 简易版防抖实现

var timer; // 维护同一个timer function debounce(fn, delay) { clearTimeout(timer); timer = setTimeout(function(){ fn(); }, delay); } // test function testDebounce() { console.log(‘test’); } document.onmousemove = () => { debounce(testDebounce, 1000); } // —————————————————————————————————————— // 在上面的代码中,会出现一个问题,var timer只能在setTimeout的父级作用域中,这样才是同一个timer,并且为了方便防抖函数的调用和回调函数fn的传参问题,我们应该用闭包来解决这些问题 // 优化后的代码 function debounce(fn, delay) { var timer; // 维护一个 timer return function () { var _this = this; // 取debounce执行作用域的this var args = arguments; if (timer) { clearTimeout(timer); } timer = setTimeout(function () { fn.apply(_this, args); // 用apply指向调用debounce的对象,相当于_this.fn(args); }, delay); }; }

// test function testDebounce(e, content) { console.log(e, content); } var testDebounceFn = debounce(testDebounce, 1000); // 防抖函数 document.onmousemove = function (e) { testDebounceFn(e, ‘debounce’); // 给防抖函数传参 } ``` 参考