深入理解节流(Throttle):原理、实现与应用场景

在前端开发中,我们经常遇到一些需要优化性能的场景,比如滚动事件、鼠标移动事件、窗口大小调整等。这些场景中,事件可能会被频繁触发,导致性能问题。节流(Throttle)是一种常见的优化技术,用于限制这些事件的触发频率,从而提高应用的性能和用户体验。


一、什么是节流?

节流的定义是:在单位时间内,最多只执行一次事件的处理函数。换句话说,节流可以确保在指定的时间间隔内,事件的处理函数最多只被触发一次。

1.1 使用场景

节流在以下场景中非常有用:

  1. 滚动事件 :当用户滚动页面时,scroll 事件会频繁触发。如果没有节流,每次触发事件都会执行相应的处理函数,这会导致性能问题。使用节流后,只有在指定的时间间隔内,才会执行一次处理函数。
  2. 鼠标移动事件 :当用户在某个元素上移动鼠标时,mousemove 事件会频繁触发。如果没有节流,每次触发事件都会执行相应的处理函数,这会导致性能问题。使用节流后,只有在指定的时间间隔内,才会执行一次处理函数。
  3. 窗口大小调整 :当用户调整窗口大小时,resize 事件会频繁触发。如果没有节流,每次触发事件都会重新计算布局,这会导致性能问题。使用节流后,只有在指定的时间间隔内,才会重新计算一次布局。

二、节流的实现

节流可以通过两种方式实现:使用 Lodash 库手写节流函数

2.1 使用 Lodash 库

Lodash 是一个非常流行的 JavaScript 工具库,提供了许多实用的函数,其中就包括 _.throttle 函数。_.throttle 函数可以将一个函数包装为一个节流函数,确保在指定的时间间隔内,最多只执行一次。

2.1.1 _.throttle 方法的参数说明

_.throttle 方法的签名如下:

javascript 复制代码
_.throttle(func, [wait = 0], [options = {}])
  • func:需要节流的函数。
  • wait:时间间隔(单位为毫秒)。默认值为 0。
  • options :可选参数,用于配置节流行为。常用选项包括:
    • leading :布尔值,如果为 true,则在时间间隔开始时立即执行一次函数。默认值为 true
    • trailing :布尔值,如果为 true,则在时间间隔结束后执行一次函数。默认值为 true
2.1.2 示例代码
html 复制代码
<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 示例代码
javascript 复制代码
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

  1. 安装 Lodash

    bash 复制代码
    npm install lodash
  2. 在组件中使用 Lodash

    javascript 复制代码
    <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

  1. 安装 Lodash

    bash 复制代码
    npm install lodash
  2. 在页面中使用 Lodash

    javascript 复制代码
    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 函数,或者手写一个节流函数来实现节流。在实际开发中,根据具体需求选择合适的实现方式。

希望这篇文章能帮助你更好地理解和使用节流技术。如果你有任何问题或建议,欢迎在评论区留言!

相关推荐
伍哥的传说2 小时前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
ai产品老杨2 小时前
解锁仓储智能调度、运输路径优化、数据实时追踪,全功能降本提效的智慧物流开源了
javascript·人工智能·开源·音视频·能源
GDAL2 小时前
Quat.js四元数完全指南
javascript·quaternion
alphageek82 小时前
Electron开源库入门教程:跨平台桌面应用框架
javascript·其他·electron·开源
小桥风满袖3 小时前
极简三分钟ES6 - ES8中字符串扩展
前端·javascript
少年阿闯~~3 小时前
CSS3的新特性
前端·javascript·css3
Anson Jiang3 小时前
浏览器标签页管理:使用chrome.tabs API实现新建、切换、抓取内容——Chrome插件开发从入门到精通系列教程06
开发语言·前端·javascript·chrome·ecmascript·chrome devtools·chrome插件
掘金安东尼3 小时前
黑客劫持:周下载量超20+亿的NPM包被攻击
前端·javascript·面试
剑亦未配妥4 小时前
移动端触摸事件与鼠标事件的触发机制详解
前端·javascript