JS性能优化之防抖节流的“妙用”:实战篇

零 JavaScript教程评论138字数 3323阅读11分4秒阅读模式

JS性能优化之防抖节流的“妙用”:实战篇

前言

在前端领域,防抖(Debounce)与节流(Throttle)是提升性能、改善用户体验的利器。本篇文章将结合具体的HTML示例代码,深入剖析这两种技术的应用场景和内部机制,以期帮助开发者更好地掌握这些实用技巧。

防抖实现原理

实现防抖的基本思路是使用setTimeoutclearTimeout。当事件第一次被触发时,设置一个定时器,在定时器到期时执行回调函数;如果在定时器到期前事件再次被触发,就清除之前的定时器并重新设置一个新的定时器。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

javascript

复制代码
  1. Javascript
  2. 深色版本
  3. 1function debounce(func, wait) {
  4. 2 let timeout;
  5. 3 return function() {
  6. 4 const context = this, args = arguments;
  7. 5 clearTimeout(timeout);
  8. 6 timeout = setTimeout(function() {
  9. 7 func.apply(context, args);
  10. 8 }, wait);
  11. 9 };
  12. 10}

防抖实战示例:搜索框输入优化

首先,我们来看一个关于防抖的示例,这涉及到搜索功能的优化。在实际的网页应用中,当用户在搜索框中输入文字时,频繁的输入事件会导致后台API的不断调用,这不仅浪费资源,还可能降低用户体验。为此,我们可以采用防抖技术来优化这一过程。
(没有防抖的input,会频繁触发事件,使控制台多次输出)
(而防抖后输入多次字符也只在其中触发一次)文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

image.png文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

xml

复制代码
  1. Html
  2. 深色版本
  3. 1<!DOCTYPE html>
  4. 2<html lang="en">
  5. 3<head>
  6. 4 <meta charset="UTF-8">
  7. 5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8. 6 <title>防抖示例</title>
  9. 7</head>
  10. 8<body>
  11. 9 <div>
  12. 10 防抖后的input <input type="text" id="unDebounce" placeholder="请输入您要搜索的用户名">
  13. 11 </div>
  14. 12 <script>
  15. 13 const inputa = document.getElementById('unDebounce');
  16. 14
  17. 15 function handleNameSearch(e) {
  18. 16 const value = e.target.value;
  19. 17 fetch('http://localhost:3000/users') // 假设这是你的API端点
  20. 18 .then(res => res.json())
  21. 19 .then(data => {
  22. 20 const users = data;
  23. 21 const filteredUsers = users.filter(user => user.name.includes(value));
  24. 22 console.log(filteredUsers);
  25. 23 });
  26. 24 }
  27. 25
  28. 26 function debounce(func, delay) {
  29. 27 let timerId;
  30. 28 return function(...args) {
  31. 29 clearTimeout(timerId);
  32. 30 timerId = setTimeout(() => {
  33. 31 func(...args);
  34. 32 }, delay);
  35. 33 };
  36. 34 }
  37. 35
  38. 36 const debouncedSearch = debounce(handleNameSearch, 500); // 500ms后执行
  39. 37 inputa.addEventListener('keyup', debouncedSearch);
  40. 38 </script>
  41. 39</body>
  42. 40</html>

在这个示例中,debounce函数接收两个参数:一个是要延迟执行的函数func,另一个是延迟时间delay。每当keyup事件触发时,debounce函数会清除已有的定时器,并重新设置一个新的定时器,确保在最后一次按键输入后的500毫秒执行handleNameSearch函数。这样,即使用户快速输入多个字符,也只会执行一次API调用,大大减少了服务器的负担。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

二、节流(Throttle)

概念

节流,旨在限制函数的执行频率,确保在一定时间间隔内只执行一次函数。它适用于需要持续监听的事件,但又不想过于频繁地执行某些操作,如拖拽元素、滚动页面等。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

实现原理

节流的核心在于设定一个固定的时间间隔,在这个间隔内无论事件触发多少次,都只执行一次回调函数。实现方式通常有两种:基于时间戳和基于定时器。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

ini

复制代码
  1. Javascript
  2. 深色版本
  3. 1function throttle(func, limit) {
  4. 2 let inThrottle;
  5. 3 return function() {
  6. 4 const args = arguments;
  7. 5 const context = this;
  8. 6 if (!inThrottle) {
  9. 7 func.apply(context, args);
  10. 8 inThrottle = true;
  11. 9 setTimeout(function() {
  12. 10 inThrottle = false;
  13. 11 }, limit);
  14. 12 }
  15. 13 };
  16. 14}

节流实战示例:实时反馈输入

接下来,让我们看看节流如何应用于实时反馈的场景,比如在输入框中输入文字时,实时显示输入结果或进行一些处理。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

image.png文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

xml

复制代码
  1. Html
  2. 深色版本
  3. 1<!DOCTYPE html>
  4. 2<html lang="en">
  5. 3<head>
  6. 4 <meta charset="UTF-8">
  7. 5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8. 6 <title>节流示例</title>
  9. 7</head>
  10. 8<body>
  11. 9 <div class="row">
  12. 10 <div>
  13. 11 节流后的input <input type="text" id="inputc" />
  14. 12 </div>
  15. 13 </div>
  16. 14 <script>
  17. 15 const inputc = document.getElementById('inputc');
  18. 16
  19. 17 const ajax = (content) => {
  20. 18 console.log(`ajax request ${content}`);
  21. 19 };
  22. 20
  23. 21 const throttle = (func, delay) => {
  24. 22 let lastTime, timerId;
  25. 23 return function(...args) {
  26. 24 const now = Date.now();
  27. 25 if (!lastTime || now - lastTime >= delay) {
  28. 26 lastTime = now;
  29. 27 func(...args);
  30. 28 } else {
  31. 29 clearTimeout(timerId);
  32. 30 timerId = setTimeout(() => {
  33. 31 lastTime = now;
  34. 32 func(...args);
  35. 33 }, delay);
  36. 34 }
  37. 35 };
  38. 36 };
  39. 37
  40. 38 const throttledAjax = throttle(ajax, 1000); // 每1000毫秒执行一次
  41. 39
  42. 40 inputc.addEventListener('keyup', (e) => {
  43. 41 throttledAjax(e.target.value);
  44. 42 });
  45. 43 </script>
  46. 44</body>
  47. 45</html>

在这个示例中,throttle函数同样接收一个函数func和一个延迟时间delay。每当keyup事件发生时,throttle函数检查上次执行是否发生在delay毫秒之前,如果是,则立即执行func;否则,它会等待delay毫秒后执行。这种方式保证了在短时间内多次触发同一事件时,func最多执行一次,从而避免了不必要的计算和资源消耗。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

结论

通过上述示例,我们可以看到,防抖和节流在实际项目中具有广泛的应用价值。防抖通过延迟执行来减少重复操作,适用于那些需要等待用户操作完全停止后才进行处理的场景;而节流则通过限制函数的执行频率,确保在一定时间内函数只被执行一次,适用于需要持续监听的事件。正确地运用这两种技术,可以显著提升应用程序的性能和用户体验。文章源自灵鲨社区-https://www.0s52.com/bcjc/javascriptjc/16874.html

零
  • 转载请务必保留本文链接:https://www.0s52.com/bcjc/javascriptjc/16874.html
    本社区资源仅供用于学习和交流,请勿用于商业用途
    未经允许不得进行转载/复制/分享

发表评论