JS—节流与防抖

简介: JS—节流与防抖

一、js防抖和节流

在进行窗口的resize、scroll、输出框内容校验等操纵的时候,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常之差。那么为了前端性能的优化也为了用户更好的体验,就可以采用防抖(debounce)和节流(throttle)的方式来到达这种效果,减少调用的频率。

二、为什么滚动scroll、窗口resize等事件需要优化

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

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

三、滚动和页面渲染前端性能优化的关系

为什么滚动需要优化?前面提到了事件中涉及到大量的位置计算、DOM操作、元素重绘等等,这些又与页面的渲染有关系,页面渲染又与前端的性能优化有关系?套娃一样,一层套着一层,每一层都联系紧密,每一层都如此平凡且重要。

review一下前端的渲染和优化

web页面展示经历的步骤:js—style—layout—paint—composite,简单回顾一下,在这里不做详细的介绍哦!

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

四、防抖Debounce

(1)防抖Debounce情景

①有些场景事件触发的频率过高(mousemove onkeydown onkeyup onscroll)

②回调函数执行的频率过高也会有卡顿现象。 可以一段时间过后进行触发去除无用操作

(2)防抖原理

一定在事件触发 n 秒后才执行,如果在一个事件触发的 n 秒内又触发了这个事件,以新的事件的时间为准,n 秒后才执行,等触发事件 n 秒内不再触发事件才执行。

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

(3)防抖函数简单实现

//简单的防抖函数
    function debounce(func, wait, immediate) {
        //定时器变量
        var timeout;
        return function () {
            //每次触发scrolle,先清除定时器
            clearTimeout(timeout);
            //指定多少秒后触发事件操作handler
            timeout = setTimeout(func, wait);
        };
    };
    //绑定在scrolle事件上的handler
    function handlerFunc() {
        console.log('Success');
    }
    //没采用防抖动
    window.addEventListener('scroll', handlerFunc);
    //采用防抖动
    window.addEventListener('scrolle', debounce(handlerFunc, 1000));
4)防抖函数的演化过程
①this event绑定问题

 

//以闭包的形式返回一个函数,内部解决了this指向的问题,event对象传递的问题
    function debounce(func, wait) {
        var timeout;
        return function () {
            var context = this;
            var args = arguments;
            clearTimeout(timeout)
            timeout = setTimeout(function () {
                func.apply(context, args)
            }, wait);
        };
    };

②立即触发问题

//首次触发执行,再次触发以后开始执行防抖函数
    //使用的时候不用重复执行这个函数,本身返回的函数才具有防抖功能
function debounce(func, wait, immediate) {
    var timeout;
    return function () {
        var context = this;
        var args = arguments;
        if(timeout) clearTimeout(timeout);
        // 是否在某一批事件中首次执行
        if (immediate) {
            var callNow = !timeout;
            timeout = setTimeout(function() {
                timeout = null;
                func.apply(context, args)
                immediate = true;
            }, wait);
            if (callNow) {
                func.apply(context, args)
            }
            immediate = false;
        } else {
            timeout = setTimeout(function() {
                func.apply(context, args);
                immediate = true;
            }, wait);
        }
    }
}

 

相关文章
|
1月前
|
JavaScript
JS封装节流函数
JS封装节流函数
15 0
|
3月前
|
JavaScript
JS中防抖和节流的区别是什么
JS中防抖和节流的区别是什么
23 0
|
1月前
|
JavaScript
|
1月前
|
JavaScript 前端开发
【JavaScript】面试手撕节流
上篇我们讲了防抖,这篇我们就谈谈防抖的好兄弟 -- 节流。这里在老生常谈般的提一下他们两者之间的区别,顺带给读者巩固下。
53 3
|
2月前
|
前端开发 JavaScript UED
【JavaScript】面试手撕防抖
防抖: 首先它是常见的性能优化技术,主要用于处理频繁触发的浏览器事件,如窗口大小变化、滚动事件、输入框内容改变等。在用户连续快速地触发同一事件时,防抖机制会确保相关回调函数在一个时间间隔内只会被执行一次。
36 0
|
3月前
|
JavaScript 前端开发
js的节流和防抖
js的节流和防抖
17 0
|
3月前
|
JavaScript 前端开发 UED
JavaScript:节流&防抖
JavaScript:节流&防抖
30 1
|
3月前
|
JavaScript 前端开发 搜索推荐
面试官:请说说JS中的防抖和节流
面试官:请说说JS中的防抖和节流
|
2月前
|
JavaScript
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
Node.js【GET/POST请求、http模块、路由、创建客户端、作为中间层、文件系统模块】(二)-全面详解(学习总结---从入门到深化)
27 0
|
2月前
|
消息中间件 Web App开发 JavaScript
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
Node.js【简介、安装、运行 Node.js 脚本、事件循环、ES6 作业队列、Buffer(缓冲区)、Stream(流)】(一)-全面详解(学习总结---从入门到深化)
72 0