面试时让你手写一个防抖和节流优化,你能写出来吗?(一)

简介: 面试时让你手写一个防抖和节流优化,你能写出来吗?(一)

前言

今天我们来聊聊防抖和节流,它们的学名为再次防抖(Debouncing)限制流节(Throttting),防抖和节流是前端开发中用于优化页面性能和提高用户体验的第二个技术。它们的目标是减少不必要的函数调用,从而减少资源消耗,提高页面数响应速度,以及提升用户交互体验。在面试过程中,面试官若是询问了你这两个概念,很大可能会叫你手写一下它们,来考察你对它们的理解。

再次防抖(Debouncing)

防抖是一种函数执行频率的方法。当一个事件被触发时,防抖会延迟一定时间执行相应的处理函数。如果在这个延迟延迟触发了相同的事件,则重新计时。这对于处理用户输入、滚动事件等触发操作间隔非常有用,可以防止过多的函数调用,从而提高性能并避免不必要的资源浪费。

我们可以用一句话来概括一下,帮助小伙伴们更好的理解:在规定的时间内没有第二次的操作,才执行逻辑

防抖的应用:

防抖的应用非常广泛,特别是在处理一些触发的事件时,可以有效地降低函数执行的频率,提升一些性能和用户体验。以下是防抖的典型应用场景:

  1. 输入框搜索: 在用户输入搜索关键词时,使用防抖可以延迟搜索请求的触发,保证用户停止输入一段时间后才执行实际的搜索操作。这减少了无谓的搜索请求,减轻了服务器负担。
  2. 窗口大小调整: 用户当调整浏览器窗口大小时,触发调整大小事件可能会非常关闭。通过防抖,可以保证只有在用户停止调整窗口大小后才触发相应的处理函数,避免不必要的计算和布局更新。
  3. 滚动事件: 处理页面滚动事件时

我们来一个简单的例子来理解一下防抖:

有时候我们在网络上提交一份东西时,有些人会一下点击个五六遍提交,或是在网络不好时,我们点击提交是没有反应,就会多点击几下再尝试,但是这样,可能会导致大量的请求,影响页面性能。

就比如这样:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button id="btn">提交</button>
    
    <script>
        let btn = document.getElementById('btn')
        btn.addEventListener('click', send)
        function send(){
            console.log('提交完成');
        }
    </script>
</body>
</html>

image.png

这里,假设send是我们点击提交后发送的请求,可以看到,我们每点击一次提交,就会发送一次请求,这样会造成不好的影响,那我们应该怎么样解决这个问题呢?那我们就要设置防抖

防抖

  • 原理在规定的时间内没有第二次的操作,才执行逻辑

这句话放到这个例子中来理解的话,就是说当我们点击了提交之后,在规定的时间内没有再次点击提交,才会发送请求,比如我们规定时间为一秒,当我们点击提交之后,假设我们在0.5s的时候点击了提交,那么第一次提交的请求就不会发送,点击第二次提交的一秒钟之内如果没有���击第三次提交,那么请求将会再1,5s时后发送。也就说,如果你在规定的时间内一直点击提交按钮,那么一次请求都不会发送,直到你点击最后一次提交时,过了1s就会发送请求。

<button id="btn">提交</button>
    <script>
        let btn = document.getElementById('btn')
        btn.addEventListener('click', debounce(send, 1000))
        function send(){
            console.log('提交完成');
        }
        function debounce(fn, delay){
            let timer;
            return function(){
                if(timer)   clearTimeout(timer)
                timer = setTimeout(function(){
                    fn()
                }, delay)
            }
        }
    </script>

代码中包含了一个闭包,闭包是指在一个函数内部创建另一个函数,并且内部函数可以访问外部函数的变量,当内部函数被返回到外部函数之外时,即使外部函数执行结束了, 但是内部函数引用了外部函数的变量,那么这些变量依旧会被保存在内层中。这里,函数就是一个闭包debounce

闭包是一个十分重要的概念,如果小伙伴不太理解闭包的话,可以看我的文章,这篇文章对闭包有着详细的解释: # 前端面试:聊聊闭包 一盏茶的功夫让你彻底掌握闭包!

function debounce(fn, delay) {
    let timer; // 在闭包内定义的变量,被内部函数访问
    // 返回的是一个新的函数,这个新函数是闭包的一部分
    return function() {
        // 在内部函数中可以访问外部函数的变量,例如这里的 timer
        if (timer) clearTimeout(timer);
        // 设置一个新的计时器,在指定的延迟时间后执行传入的函数 fn
        timer = setTimeout(function() {
            fn(); // 执行传入的函数
        }, delay);
    };
}

现在让我们详细解释一下闭包的一些重要概念:

  1. 函数内部定义的变量:debounce函数内部,有一个变量timer被定义。由于内部函数(通过return function() {...}返回的那个函数)可以访问外部函数的变量,所以timer成为了一个闭包变量。这意味着在返回的函数中,您可以使用和修改timer变量,并且其生命周期结束了debounce函数的调用。
  2. 返回一个新的函数: debounce函数返回了一个新的函数,这个函数就是闭包的一部分。这个新函数可以访问外部函数的变量(这里是和),即使在函数执行完毕之后,timer这些delay变量debounce的状态也被保留了。
  3. 使用外部变量: 在返回的函数内,使用了timer变量。该变量在每次函数被调用时都被检查和更新,确保在指定的延迟时间内只执行一次指定的函数fn

通过这种方式,debounce函数可以灵活地创建具有定制延迟执行行为的函数。在这里,它用于一个防抖函数,以确保创建在指定的时间内只执行一次确定的函数。

让我们来看看效果:

image.png

当我们点击了最后一次提交后,过了规定时间才会执行请求

下一篇文章我们会继续拓展一下防抖,并且讲讲节流。

总结

防抖

在规定的时间内没有第二次的操作,才执行逻辑

相关文章
|
前端开发 JavaScript Java
面试官:什么是防抖和节流?如何实现?应用场景?
面试官:什么是防抖和节流?如何实现?应用场景?
272 0
|
XML JSON 数据格式
【第20期】一文读懂Restful接口规范
【第20期】一文读懂Restful接口规范
1868 0
|
缓存 JSON 前端开发
CORS 详解,终于不用担心跨域问题了
CORS 详解,终于不用担心跨域问题了
8425 1
CORS 详解,终于不用担心跨域问题了
|
JavaScript
vue elementUI select下拉框设置默认值
vue elementUI select下拉框设置默认值
1925 0
|
11月前
|
前端开发
Promise.race() 方法在什么场景下使用?
`Promise.race()` 方法通过其独特的竞争机制,在需要快速获取结果、设置超时控制、实现快速失败以及根据条件动态选择异步操作等场景中,能够提供简洁有效的解决方案,帮助优化异步操作的执行流程和提高系统的响应性能。
|
JSON 前端开发 JavaScript
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
该文章提供了Webpack的基础入门指南,涵盖安装配置、基本使用、加载器(Loaders)、插件(Plugins)的应用,以及如何通过Webpack优化前端项目的打包构建流程。
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
|
11月前
|
自然语言处理 安全 前端开发
什么是CMS?CMS适合搭建什么网站?
CMS(内容管理系统)用于快速搭建、管理和发布网站内容。它支持自定义板块,降低建站门槛。CMS分为独立CMS和SaaS CMS两种类型,主要功能包括角色分配、SEO优化、多语言支持等。建站流程包括确定需求、选择系统、购买域名和主机、安装系统、选择模板、扩展栏目、添加内容、上线和维护。PageAdmin CMS是一款优秀的建站系统,推荐免费试用。
524 1
|
Web App开发 前端开发 UED
移动端适配布局指南:打造完美用户体验的秘密武器
【8月更文挑战第26天】在Web前端开发中,选择合适的移动端适配方案对确保跨设备的良好显示与用户体验至关重要。常用方案包括:媒体查询实现响应式布局;百分比、flexbox与CSS Grid布局提供更灵活的设计;结合viewport元标签和rem单位实现等比缩放;利用第三方库如Bootstrap加速开发。实践中应综合运用这些技术,并通过广泛测试保证兼容性和效果。
408 4
|
小程序 前端开发 API
微信小程序全栈开发中的多端适配与响应式布局是一种高效的开发模式。
探讨小程序全栈开发中的多端适配与响应式布局,旨在实现统一的用户体验。多端适配包括平台和设备适配,确保小程序能在不同环境稳定运行。响应式布局利用媒体查询和弹性布局技术,使界面适应各种屏幕尺寸。实践中需考虑兼容性、性能优化及用户体验,借助跨平台框架如Taro或uni-app可简化开发流程,提升效率。
349 1
|
移动开发 前端开发 JavaScript
说一说你对混合开发(Hybrid Development)的了解。
混合开发(Hybrid App)结合Web和Native技术,实现跨平台应用开发,降低工作量和时间。使用JavaScript等Web技术提升开发效率,通过优化提供接近原生体验。混合应用可即时更新,维护灵活,成本效益高。React Native和Flutter等框架支持混合开发,丰富的社区资源加速开发进程。网易云音乐等成功案例证明其可行性。随着技术进步,混合开发前景广阔。
288 1