滚动加载必须加节流,因scroll事件每秒触发60–120次,不节流会导致重复请求、卡顿和接口超限;推荐300ms起步,配合loading锁与100px阈值实现健壮加载。

滚动加载更多用节流优化,核心是控制“检测是否到底部”这个逻辑的执行频率,避免每次滚动都计算、判断、发请求,从而防止重复加载、卡顿或接口超限。
为什么滚动加载必须加节流
浏览器滚动时 scroll 事件每秒可能触发 60–120 次。若直接在监听器里写加载逻辑:
- 反复调用 getBoundingClientRect() 或 scrollTop + clientHeight >= scrollHeight 计算,消耗 CPU
- 可能在一次滚动中多次触发加载,造成重复请求、数据错乱、loading 状态闪烁
- 未加节流 + 未设 loading 锁,极易出现“滚一下发三遍请求”的问题
节流参数怎么选:300ms 是常用起点
300ms 能兼顾响应及时性与性能——用户明显感知不到延迟,又把高频触发压成约 3–4 次/秒。实际可按场景微调:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 列表项高度小、内容密(如微博流)→ 可缩至 200ms,提升触底灵敏度
- 长图文卡片、加载耗时高 → 建议 350–400ms,留出 JS 执行余量
- 移动端惯性滚动强 → 必须启用 trailing: true,确保滚动结束前兜底检测一次
加载逻辑要配合 loading 锁和临界判断
节流只管“调用频次”,不解决“不该调还调”的问题。真正健壮的实现需三层防护:
- 节流包装检测函数:只让“是否该加载”这个判断逻辑被节流
-
loading 状态锁:请求发出后设
loading = true,成功/失败后才重置 - 距离底部阈值(如 100px):不等完全到底,提前触发,避免用户停在临界点却无响应
示例关键结构:
let loading = false;
const threshold = 100;
<p>function checkLoadMore() {
if (loading) return;
const { scrollTop, clientHeight } = document.documentElement;
const { scrollHeight } = document.body;
if (scrollHeight - scrollTop - clientHeight </p><p>window.addEventListener('scroll', throttle(checkLoadMore, 300, {
leading: true,
trailing: true
}), { passive: true });</p>别漏掉 passive: true 这个底层开关
现代浏览器默认将 scroll 监听器视为可能调用 preventDefault(),因此强制同步执行回调,哪怕里面只有一行 console.log —— 这会直接阻塞滚动帧,导致卡顿。加上 { passive: true } 告诉浏览器:“我不会阻止默认滚动”,浏览器就能异步调度事件,配合节流效果翻倍。










