在前端开发中,我们经常遇到一些需要优化性能的场景,比如滚动事件、鼠标移动事件、窗口大小调整等。这些场景中,事件可能会被频繁触发,导致性能问题。节流(Throttle)是一种常见的优化技术,用于限制这些事件的触发频率,从而提高应用的性能和用户体验。
一、什么是节流?
节流的定义是:在单位时间内,最多只执行一次事件的处理函数。换句话说,节流可以确保在指定的时间间隔内,事件的处理函数最多只被触发一次。
1.1 使用场景
节流在以下场景中非常有用:
- 滚动事件:当用户滚动页面时,
scroll
事件会频繁触发。如果没有节流,每次触发事件都会执行相应的处理函数,这会导致性能问题。使用节流后,只有在指定的时间间隔内,才会执行一次处理函数。 - 鼠标移动事件:当用户在某个元素上移动鼠标时,
mousemove
事件会频繁触发。如果没有节流,每次触发事件都会执行相应的处理函数,这会导致性能问题。使用节流后,只有在指定的时间间隔内,才会执行一次处理函数。 - 窗口大小调整:当用户调整窗口大小时,
resize
事件会频繁触发。如果没有节流,每次触发事件都会重新计算布局,这会导致性能问题。使用节流后,只有在指定的时间间隔内,才会重新计算一次布局。
二、节流的实现
节流可以通过两种方式实现:使用 Lodash 库 和 手写节流函数。
2.1 使用 Lodash 库
Lodash 是一个非常流行的 JavaScript 工具库,提供了许多实用的函数,其中就包括 _.throttle
函数。_.throttle
函数可以将一个函数包装为一个节流函数,确保在指定的时间间隔内,最多只执行一次。
2.1.1 _.throttle
方法的参数说明
_.throttle
方法的签名如下:
_.throttle(func, [wait = 0], [options = {}])
func
:需要节流的函数。wait
:时间间隔(单位为毫秒)。默认值为 0。options
:可选参数,用于配置节流行为。常用选项包括:leading
:布尔值,如果为true
,则在时间间隔开始时立即执行一次函数。默认值为true
。trailing
:布尔值,如果为true
,则在时间间隔结束后执行一次函数。默认值为true
。
2.1.2 示例代码
<body>
<div style="height: 200px; width: 200px; background-color: pink;">
</div>
<script src="https://cdn.jsdelivr.net/npm/lodash/lodash.min.js"></script>
<script>
console.log('loaded');
// 节流
// 定义:在单位时间内,最多只执行一次事件的处理函数
// 使用场景:滚动事件、鼠标移动事件、窗口大小调整等
// 需求:鼠标在盒子上一滑动,里面的数字就发生变化 + 1
// TODO.1 没做节流处理的代码
// const box = document.querySelector('div');
// let i = 1;
// const mouseMove = () => box.innerText = i++;
// box.addEventListener('mousemove', mouseMove);
// TODO.2 进行节流处理(此处我们处理的方式是鼠标在盒子上移动,每500ms最多触发一次)
/* 实现方式
1. lodash 库提供的节流来处理
2. 手写一个节流函数来处理
*/
// TODO.3 lodash 库 处理
// 该库提供的 _.throttle(function, [wait = 0])函数,作用是在wait毫秒内最多调用一次function
const box = document.querySelector('div');
let i = 1;
const mouseMove = () => box.innerText = i++;
box.addEventListener('mousemove', _.throttle(mouseMove, 500)); // 此时每500ms最多触发一次加1事件
</script>
</body>
在上面的代码中,我们使用了 Lodash 的 _.throttle
函数,将 mouseMove
函数包装为一个节流函数。只有在每 500 毫秒内,才会触发一次 mouseMove
函数。
2.2 手写节流函数
如果你不想使用 Lodash 库,也可以手写一个节流函数。手写节流函数的实现相对简单,但需要理解定时器的使用。
2.2.1 示例代码
function throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
}, limit);
}
};
}
const box = document.querySelector('div');
let i = 1;
const mouseMove = () => box.innerText = i++;
box.addEventListener('mousemove', throttle(mouseMove, 500));
在上面的代码中,我们定义了一个 throttle
函数,它接受两个参数:func
是需要节流的函数,limit
是时间间隔(单位为毫秒)。throttle
函数返回一个新的函数,每次触发事件时,都会检查是否在时间间隔内已经触发过函数。如果已经触发过,则不会再次触发,直到时间间隔结束。
三、Lodash 的 CDN 使用方法
以下是常用的 Lodash 库的 CDN 地址:
jsDelivr
- 最新版本:
https://cdn.jsdelivr.net/npm/lodash/lodash.min.js
- 指定版本:
https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js
unpkg
- 最新版本:
https://unpkg.com/lodash/lodash.min.js
- 指定版本:
https://unpkg.com/lodash@4.17.21/lodash.min.js
BootCDN
- 最新版本:
https://cdn.bootcdn.net/ajax/libs/lodash.js/latest/lodash.min.js
- 指定版本:
https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js
你可以根据自己的需求选择合适的 CDN 地址来引入 Lodash 库。
四、在 Vue 或 Next.js 项目中使用 Lodash
4.1 在 Vue 项目中使用 Lodash
安装 Lodash:
npm install lodash
在组件中使用 Lodash:
<template> <div @mousemove="throttledMousemove"> {{ count }} </div> </template> <script> import _ from 'lodash'; export default { data() { return { count: 0, }; }, methods: { mousemove() { this.count += 1; }, }, created() { this.throttledMousemove = _.throttle(this.mousemove, 500); }, }; </script> <style> div { height: 200px; width: 200px; background-color: pink; } </style>
4.2 在 Next.js 项目中使用 Lodash
安装 Lodash:
npm install lodash
在页面中使用 Lodash:
import _ from 'lodash'; import { useState } from 'react'; export default function Home() { const [count, setCount] = useState(0); const mousemove = () => { setCount(count + 1); }; const throttledMousemove = _.throttle(mousemove, 500); return ( <div onMouseMove={throttledMousemove}> {count} </div> ); }
五、节流与防抖的区别
节流和防抖(Debounce)都是用于优化事件触发频率的技术,但它们的实现方式和应用场景有所不同。
- 节流:在单位时间内,最多只执行一次事件的处理函数。适用于滚动事件、鼠标移动事件、窗口大小调整等场景。
- 防抖:在单位时间内频繁触发事件时,只执行最后一次事件的处理函数。适用于输入框的实时验证、窗口大小调整等场景。
六、总结
节流是一种非常实用的优化技术,可以有效减少事件的触发频率,提高应用的性能和用户体验。你可以通过使用 Lodash 库的 _.throttle
函数,或者手写一个节流函数来实现节流。在实际开发中,根据具体需求选择合适的实现方式。
希望这篇文章能帮助你更好地理解和使用节流技术。如果你有任何问题或建议,欢迎在评论区留言!