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

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

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

前言

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

防抖实现原理

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

javascript

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

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

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

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

xml

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

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

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

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

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

xml

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

发表评论