JavaScript 如何做节流

你有没有过这样的经历:刷短视频时,手指快速滑过屏幕,APP却不会因为你连续的滑动反复刷新页面数据;或者你在搜索框里输入关键词时,哪怕敲得再快,搜索联想词也不会每打一个字就跳出来刷新一次——这些流畅的背后,藏着前端开发里一个实用的小技巧:节流。很多人在接触这个概念时会觉得有点绕,其实用生活化的例子一讲,就能轻松搞懂,还能学会怎么用它来写JavaScript代码。

先搞懂:节流到底是在防什么“麻烦”

想象你去奶茶店买奶茶,队伍很长,你每往前挪一步就喊一次“老板,我要一杯珍珠奶茶”,老板根本没法专心做单,只能反复停下手上的活回应你。如果换成节流的逻辑,就是你每过5分钟才喊一次“老板,我要一杯珍珠奶茶”,哪怕你每隔1分钟就往前挪一步,老板也只会按约定的5分钟响应一次——这样既不耽误你买奶茶,也不会让老板忙乱。

JavaScript 如何做节流

对应到前端里,像窗口拖动、鼠标移动、页面滚动、输入框输入这些事件,触发频率特别高:比如你拖动浏览器窗口,1秒里可能触发几十次resize事件,要是每次都执行对应的代码(比如调整页面布局),浏览器就会像被催命一样卡顿,甚至直接崩溃。节流的作用,就是把这些高频事件的触发“打包”,规定每间隔固定时间才执行一次代码,避免资源浪费,让页面更流畅。

写个简单的节流函数,跟着例子一步步来

很多人觉得节流的代码难写,其实核心逻辑就一句话:记录上次执行的时间,和当前时间做对比,只有间隔时间达标才执行代码。我们用最常用的“时间戳版节流”举例子,代码就像给事件加了个“定时器开关”:

`javascript

// 定义节流函数,参数是要执行的函数和间隔时间(比如1000毫秒)

function throttle(fn, delay) {

// 记录上次执行的时间,初始设为0

let lastTime = 0;

// 返回一个新函数,用来替代原来的高频触发代码

return function() {

// 获取当前时间戳

const now = Date.now();

// 只有当前时间减上次执行时间,大于等于设定的间隔,才执行代码

if (now - lastTime >= delay) {

fn.apply(this, arguments); // 执行原来的功能函数

lastTime = now; // 更新上次执行时间

}

}

}

`

把这个函数用到刚才说的“页面滚动监听”场景里就很简单了:比如要监听用户滚动到底部加载更多内容,要是不用节流,用户滚动时会反复发请求;用了节流,每3秒才检查一次滚动位置,既不会漏看用户到底部的操作,也不会给服务器添乱:

`javascript

// 给滚动事件加节流,间隔3000毫秒

window.addEventListener('scroll', throttle(function() {

const scrollTop = document.documentElement.scrollTop;

const clientHeight = document.documentElement.clientHeight;

const scrollHeight = document.documentElement.scrollHeight;

// 当滚动高度接近页面底部时,执行加载逻辑

if (scrollTop + clientHeight >= scrollHeight - 10) {

console.log('加载更多内容中...');

}

}, 3000));

`

别踩这些容易忽略的小细节

节流虽然好用,但也有两个常见的坑要避开:第一个是“最后一次触发被遗漏”,比如用户滑动页面到最后,节流函数的间隔时间还没到,就不会执行最后一次的加载逻辑,这时候可以用“定时器版节流”补全最后一次触发,相当于给最后一次触发加了个超时兜底;第二个是间隔时间的设置,不能太短也不能太长,太短起不到节流效果,太长又会让用户觉得页面反应慢,一般前端常用的间隔是100-300毫秒,根据场景调整就好。

说到底,节流就是前端优化里的“时间管理大师”,把高频重复的操作整理成规律的执行节奏,既让页面跑起来更顺,也减轻了服务器的压力。只要记住“记录上次执行时间、对比间隔后再执行”的核心逻辑,再配合生活化的场景,用起来其实一点都不难。

上一篇 JavaScript 如何做函数柯里化