前端进阶版本 ,性能优化—-防抖、节流、重绘与回流

目录

【防抖】

【节流】

重绘(repaint)

回流(reflow):又叫重排(layout)

工作中要如何避免大量使用重绘与回流?

常见的会导致回流的元素


【防抖】

任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。

复制代码
/**
 * 防抖函数
 * @author vision
 * @param {执行函数} fn
 * @param {延迟} delay
 */
export function debounce(fn, delay) {
  let timer = null;
  return function() {
    let context = this;
    let arg = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, arg);
    }, delay);
  };
}

/**
 * 防抖函数 - 箭头函数
 * @param {执行函数} fn
 * @param {延迟} delay
 */
export const debounceEs6 = (fn, delay) => {
  let timer = null;
  return (...rest) => {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn(rest);
    }, delay);
  };
};

【节流】

指定时间间隔内只会执行一次任务。

复制代码
    function throttle(fn) {
      // 通过闭包保存一个标记
      let canRun = true;
      return function() {
        // 在函数开头判断标志是否为 true,不为 true 则中断函数
        if(!canRun) {
          return;
        }
        // 将 canRun 设置为 false,防止执行之前再被执行
        canRun = false;
        // 定时器
        setTimeout( () => {
          fn.call(this, arguments);
          // 执行完事件(比如调用完接口)之后,重新将这个标志设置为 true
          canRun = true;
        }, 1000);
      };
    }

重绘(repaint)

当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此损耗较少。

常见的重绘操作有:

  • 改变元素颜色改变
  • 元素背景色
  • more ......

回流(reflow):又叫重排(layout)

当元素的尺寸、结构或者触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。

常见的回流操作有:

  • 页面初次渲染
  • 浏览器窗口大小改变
  • 元素尺寸/位置/内容发生改变
  • 元素字体大小变化
  • 添加或者删除可见的 DOM 元素
  • 激活 CSS 伪类(:hover......)
  • more ......

重点:回流必定会触发重绘,重绘不一定会触发回流。重绘的开销较小,回流的代价较高。

工作中要如何避免大量使用重绘与回流?

  • 避免频繁操作样式,可汇总后统一一次修改
  • 尽量使用 class 进行样式修改,而不是直接操作样式
  • 减少 DOM 的操作,可使用字符串一次性插入

复制代码
以下资料来自于 https://juejin.im/post/5e096d63e51d4558381e9906#heading-29

常见的会导致回流的元素

  • 常见的几何属性有 width、height、padding、margin、left、top、border 等等。
  • 最容易被忽略的操作:获取一些需要通过即时计算得到的属性,当你要用到像这样的属性:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight 时,浏览器为了获取这些值,也会进行回流。
  • 当我们调用了 getComputedStyle 方法,或者 IE 里的 currentStyle 时,也会触发回流。原理是一样的,都为求一个"即时性"和"准确性"。

避免方式:

  • 避免逐条改变样式,使用类名去合并样式

  • 将 DOM "离线",使用DocumentFragment

  • 提升为合成层,如使用will-change

    #divId {
    will-change: transform;
    }

优点:

  • 合成层的位图,会交由 GPU 合成,比 CPU 处理要快
  • 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层
  • 对于 transform 和 opacity 效果,不会触发 layout 和 paint

注意:

部分浏览器缓存了一个 flush 队列,把我们触发的回流与重绘任务都塞进去,待到队列里的任务多起来、或者达到了一定的时间间隔,或者"不得已"的时候,再将这些任务一口气出队。但是当我们访问一些即使属性时,浏览器会为了获得此时此刻的、最准确的属性值,而提前将 flush 队列的任务出队。

原文链接:https://blog.csdn.net/jiepan9178/article/details/104264816

相关推荐
丷丩5 分钟前
MapLibre GL JS第11课:获取鼠标指针坐标
前端·javascript·gis·地图·mapbox·maplibre gl js
代码AI弗森13 分钟前
前端周刊第 467 期[特殊字符] 本期精选目录
前端
随便的名字14 分钟前
前端路由的底层逻辑:URL 中 # 和 ? 的区别与关系详解
前端
kongba00716 分钟前
ttyd Web终端安装指南(OpenCloudOS 9)
linux·前端
zhoumeina9916 分钟前
前端串行合成流程 + 每张图上传接口
前端·状态模式
风骏时光牛马18 分钟前
Swift 基于MVVM架构实现完整列表数据展示与交互功能实战案例
前端
就叫_这个吧27 分钟前
JavaScript基础数据类型、运算符、数组、函数的定义及DOM方式应用
开发语言·前端·javascript
作业逆流成河34 分钟前
别再一次性重构枚举了:如何把一个真实后台项目的状态字典,渐进式迁移到enum-plus?
前端·javascript·开源
暗不需求34 分钟前
React 性能优化秘籍:深入理解 `useMemo` 与 `useCallback`
前端·react.js·面试
专注VB编程开发20年40 分钟前
我制作excel工作簿的选项卡,发给deep seek, 昨天修改了一天
前端·vue.js·excel