JS 防抖 与 节流

举报
福州司马懿 发表于 2023/04/23 13:31:42 2023/04/23
【摘要】 滚动对页面渲染的影响web页面渲染会经历如下步骤:js加载 —> style加载 —> layout(确定布局) —> paint(页面绘制) —> composite(组合控件)网页生成的时候,至少会渲染(Layout+Paint)一次。用户访问的过程中,还会不断重新的重排(reflow)和重绘(repaint),用户scroll行为和resize行为会导致页面不断的进行重新渲染,如果间...

滚动对页面渲染的影响

web页面渲染会经历如下步骤:js加载 —> style加载 —> layout(确定布局) —> paint(页面绘制) —> composite(组合控件)

网页生成的时候,至少会渲染(Layout+Paint)一次。用户访问的过程中,还会不断重新的重排(reflow)和重绘(repaint),用户scroll行为和resize行为会导致页面不断的进行重新渲染,如果间隔频繁,容易造成浏览器卡帧。

为什么滚动scroll、窗口resize需要优化

滚动事件的应用很频繁:图片懒加载、下滑自动加载数据、侧边浮动导航栏等。

在绑定scroll、resize事件时,但它发生的时候,它被触发的频率非常高,间隔很近。在日常开发的页面中,事件中涉及到的大量的位置计算、DOM操作、元素重绘等等这些都无法在下一个scroll事件出发前完成的情况下,浏览器会卡帧。

防抖与节流

在进行窗口的resize、scroll、输出框内容校验等操纵的时候,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致浏览器卡顿。为了用户更好的体验,就可以采用防抖(debounce)和节流(throttle)的方式来减少调用的频率,减轻浏览器的负担。

防抖Debounce

使用情景

  • 有些场景事件触发的频率过高(mousemove onkeydown onkeyup onscroll)
  • 回调函数执行的频率过高也会有卡顿现象。 可以一段时间过后进行触发去除无用操作

原理

当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

代码示例

以下是一个简单的JavaScript代码示例,它实现了一个基本的防抖功能:

function debounce(func, delay) {
  let timer = null;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      func.apply(context, args);
    }, delay);
  }
}

这个代码定义了一个名为debounce的函数,它接受两个参数:要防抖的函数和防抖的时间间隔。当调用debounce函数时,它会返回一个新的函数,这个新函数将被用来代替原来的函数。

每次调用新函数时,它会清除之前设置的定时器,并创建一个新的定时器。如果在指定时间间隔内再次调用新函数,定时器将被清除并重新设置。只有在指定时间间隔内没有再次调用新函数时,定时器才会在最后一次调用后触发,并调用原始函数。

这个防抖函数可以用于限制某些操作的执行频率,例如在用户连续输入时进行搜索操作。这可以减少不必要的网络请求和计算资源消耗。

节流Throttle

使用情景

  • 图片懒加载
  • ajax数据请求加载

原理

当持续触发事件时,保证一定时间段内只调用一次事件处理函数。

代码示例

以下是一个简单的JavaScript代码示例,它实现了一个基本的节流功能:

function throttle(func, delay) {
  let timer = null;
  return function() {
    const context = this;
    const args = arguments;
    if (!timer) {
      timer = setTimeout(function() {
        func.apply(context, args);
        timer = null;
      }, delay);
    }
  }
}

这个代码定义了一个名为throttle的函数,它接受两个参数:要节流的函数和节流的时间间隔。当调用throttle函数时,它会返回一个新的函数,这个新函数将被用来代替原来的函数。

每次调用新函数时,它会检查是否已经设置了一个定时器。如果没有,它会创建一个新的定时器,并在指定的时间间隔后调用原始函数。如果已经设置了定时器,则新函数将不执行任何操作。

这个节流函数可以用于限制某些操作的执行频率,例如在用户滚动页面时更新页面元素的位置。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。