掌握全栈防抖,避免上午入职下午跑路

235 阅读4分钟

在现代Web开发中,优化性能和提升用户体验是开发者们追求的两个重要目标。随着前后端分离架构的普及,前端和后端都面临着如何处理频繁触发事件的问题,例如窗口调整大小、滚动、输入框内容变化等。为了解决这些问题,防抖(Debouncing)作为一种常见的优化策略被广泛应用。本文将深入探讨全栈防抖的概念、原理以及在实际项目中的应用。

在进行深入研究之前,先来了解下基本概念。

何为防抖

防抖(Debouncing)是一种编程模式,它是用来确保一个函数不会在短时间被连续执行,而是在连续输入的最后一次才执行。这样可以减少重复操作。试想一下,我们创建一个搜索框,如果敲一个字母就发送一次请求,且同时有几百万人使用,那它的服务器岂不是在一瞬间就会崩溃。全栈防抖就是在前端和后端都应用防抖技术,来减少资源不必要的消耗。

前后端分离

在web开发中,通常会使用前后端分离这种架构进行开发,这是将前端(用户界面)和后端(业务逻辑和服务端API)分开开发和部署,通过定义好的API接口连接在一起。这样可以减少相互依赖,避免混合在一起,有利于后期的更新与维护。

  • 前端:在前端开发中,使用live-server服务,来监听文件变化并自动刷新浏览器,在默认情况下监听5500端口。
  • 后端:在后端则使用json-server,是一个RESTful API模拟器,它读取本地文件并提供CRUD(创建、读取、更新、删除)操作,默认在3000端口上。

在这里,我们来创建一个搜索框来详细分析下。

项目

初始化项目

在正式写代码之前,先要分别创建前段项目(live-server)和后端项目(json-server)并初始化后端项目。

npm init -y//将当前文件初始化为后端项目
npm i json-server//从`npm`中导出并安装`json-server`与当前文件中。
npm i //安装`json-server`中所有依赖项。

这样就创建了一个后端项目并导入json-server。在文件夹中会出现一个package.json文件。如下图所示:

Snipaste_2024-12-08_23-08-39.png

后端部分

后端部分比较简单,只需要创建一个json文件用来存储数据即可。

Snipaste_2024-12-08_23-52-14.png

前端部分
<!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>
  <div>
    <label for="unDebounceInput">用户搜索</label>
    <input 
      type="text"
      id="unDebounceInput"
      placeholder="请输入要搜索的用户名字"
    >
  </div>
  <ul id="users">

  </ul>
  <script>
  const oUL = document.querySelector('#users');
  // 通往后端接口
  const oInput = document.getElementById('unDebounceInput');
  // 当作为事件的处理函数来用时,this 指向事件的目标元素
  const debounceNameSearch = debounce(handleNameSearch, 500);
  oInput.addEventListener('keyup', debounceNameSearch)
  
 function handleNameSearch() {
    let value = oInput.value.trim();
    if (value === '') {
      oUL.innerHTML = '';
      return;
    }
    fetch('http://localhost:3001/users')
      .then(res => res.json())
      .then(users => {
        // console.log(users);
        // 箭头函数的优雅 + filter 的新功能
        const filterUsers = users.filter(
          user =>  user.name.includes(value)
        )
        // Array 在es6 中新增的方法
        oUL.innerHTML = filterUsers.map(user =>  `
          <li>
            ${user.name}
          </li>
          `
        ).join("")
        // for(let user of filterUsers) {
        //   const oLI = document.createElement('li');
        //   oLI.innerText = user.name;
        //   oUL.appendChild(oLI);
        // }
        
      })
  }
   </script>
</body>
</html>

以上代码就创建了一个搜索功能,但该代码有一个致命的问题——没有防抖。这也就意味着我们每敲写一个字母,就会向服务器发送一次请求。这种情况会严重影响代码性能和用户体验,消耗CPU内存甚至导致服务器崩溃。当这种情况发生时,那么恭喜你,准备跑路吧。

而处理这种情况也很简单,只需要在后面添加防抖即可。而防抖实际就是定时器的循环使用,将一个即将要执行的函数交给debounce()高阶函数去优化,来减少执行次数,本次输入时会删除定时器,在输入完成后又添加一个定时器,如此往复,直到最后一次输入完成后才发送一次请求。

 function debounce(fn, delay) {
    return function() { 
      clearTimeout(id);
     fn.id = setTimeout(() =>{
        fn()
      },delay)
    }
  }

以上代码就是完成了防抖的添加,可以减少请求次数、减轻服务器的负载,还可以提升用户体验。

总结

防抖技术在面试八股文中位列第一,是进入大厂前必须掌握的重要技术。前后端分离和全栈防抖的技术相结合,全栈开发者便可以提高开发效率,开发出易于后期维护和扩展,并提高用户体验的web程序。深入了解并掌握这些技术,便于应对今后开发web的挑战。