如何实现Javascript的无限滚动_怎样用Javascript优化长列表渲染?


直接监听 scroll 易卡顿因触发频率过高导致重排重绘,应改用 IntersectionObserver 实现触底加载,配合 cursor 分页与 AbortController 避免状态混乱。

为什么直接监听 scroll 容易卡顿?

因为原生 scroll 事件触发频率极高(每毫秒都可能触发),若在回调里直接调用 fetch 或操作 DOM,浏览器会频繁重排重绘,导致掉帧。尤其在低端设备或列表项含图片/复杂样式时,scrollTop 检查 + appendChild 组合极易引发 Layout Thrashing

关键不是“要不要监听”,而是“什么时候响应”。必须加节流或采用更稳定的检测方式:

  • IntersectionObserver 替代 scroll + 手动计算 —— 它由浏览器原生调度,不阻塞主线程
  • 若必须用 scroll,至少用 requestIdleCallbacksetTimeout(..., 0) 延迟到空闲期执行加载逻辑
  • 避免在滚动中反复读取 document.documentElement.scrollHeightscrollTop,这些是强制同步布局的“脏读”

怎么用 IntersectionObserver 实现可靠触底加载?

它不依赖滚动位置数值,而是观察一个“占位元素”(sentinel)是否进入视口。只要它一出现,就说明该加载下一页了。这种方式对虚拟滚动、动态高度、甚至 CSS transform 位移都兼容。

注意三个易错点:

  • rootMargin 要设为类似 "0px 0px 200px 0px",提前 200px 触发,避免用户已看到空白才开始请求
  • 观察器创建后,必须确保 sentinel 元素真实存在于 DOM 中;若用 React/Vue 动态渲染,需在节点挂载后再 observe()
  • 加载中要 unobserve(sentinel),防止重复触发;新数据追加后,再 observe() 新的 sentinel
const observer = new IntersectionObserver(
  (entries) => {
    if (entries[0].isIntersecting && !loading) {
      observer.unobserve(sentinel);
      loadMore().finally(() => observer.observe(sentinel));
    }
  },
  { rootMargin: "0px 0px 200px 0px" }
);
observer.observe(sentinel);

长列表卡顿的真正瓶颈往往不在 JS,而在 DOM 节点数量

渲染 1 万条

  • ,哪怕内容为空,浏览器也要维护上万个 Layout Object。此时任何优化 JS 逻辑都是隔靴搔痒。必须做 DOM 节点复用(即“窗口化”)。

    核心策略是只保留可视区域 ±1~2 屏的 DOM 节点,其余用 height 占位:

    • getBoundingClientRect()scrollTop + 容器高度算出当前应显示的起始索引
    • 所有列表项用固定高度(或预估高度),通过 transform: translateY() 定位,避免影响文档流
    • DocumentFragment 批量更新,减少重排次数

    如果业务允许,直接用成熟库如 react-windowvue-virtual-scroller,它们已处理好滚动精度、键盘导航、动态高度等边缘 case。

    服务端分页参数和前端加载状态怎么对齐?

    前端无限滚动常误用 page=1, page=2... 这类偏移式分页,导致翻页时插入新数据后,用户滚动位置突变、重复加载、或漏数据。正确做法是用游标(cursor)分页:

    • 后端返回下一页的 cursor(例如最后一条记录的 idcreated_at 时间戳)
    • 前端只存这个 cursor,下次请求带过去,不依赖页码或 offset
    • 加载中状态必须绑定到具体 cursor 请求,避免用户快速滚动多次触发多并发请求,造成状态混乱

    另外,AbortController 必须用上:每次新请求前 abort 上一个未完成的请求,否则旧请求返回后覆盖新数据,UI 就会“倒退”。


    # css  # vue  # react  # javascript  # java  # js  # 前端  # 浏览器  # app  # 后端  # win  # 并发请求  # 重绘 


    相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 网络优化76771 】 【 技术知识130152 】 【 IDC云计算60162 】 【 营销推广131313 】 【 AI优化88182 】 【 百度推广37138 】 【 网站推荐60173 】 【 精选阅读31334


    相关推荐: Mac系统更新下载慢或失败怎么办_解决macOS升级问题【方法】  Win10如何备份驱动程序_Win10驱动备份步骤【攻略】  Windows蓝屏错误0x00000018怎么处理_驱动初始化错误解决  Win11怎么更改任务栏颜色_Windows11个性化重音色设置  Win10怎样卸载自带Edge_Win10卸载Edge浏览器步骤【教程】  Win11怎么开启自动HDR画质_Windows11显示设置HDR选项  VSC怎样在Linux运行PHP_Ubuntu系统配置步骤【操作】  Python正则表达式实战_模式匹配说明【教程】  PHP中require语句后直接调用返回对象方法的语法解析  XML的“混合内容”是什么 怎么用DTD或XSD定义  Windows10蓝屏SYSTEM_SERVICE_EXCEPTION_Win10驱动冲突排查  Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤  Drupal 中 HTML 链接被重复转义导致渲染异常的解决方案  Mac的访达(Finder)怎么用_Mac文件管理入门教程【详解】  Windows如何拦截腾讯视频广告_Windows拦截腾讯视频广告方法【方法】  如何使用Golang捕获测试日志_Golang testing日志记录方法  php下载安装后swoole扩展怎么安装_异步框架支持【汇总】  MySQL 中使用 IF 和 CASE 实现查询字段条件化显示  如何在 Windows 11 中使用 AlomWare 工具箱  如何在Golang中操作嵌套切片指针_Golang多维slice修改  如何在Golang中定义接口_抽象方法和多态实现  php订单日志怎么导出excel_php导出订单日志到表格教程【教程】  c++的static关键字有什么用 静态变量和静态函数的应用场景【教程】  手机php文件怎么变成mp4_安卓苹果打开php转mp4方法【教程】  php转exe用什么工具打包快_高效打包软件推荐【汇总】  Win11声音忽大忽小怎么办 Win11音频增强功能关闭教程【修复】  php在Linux怎么部署_LNMP环境搭建PHP服务的详细指南【指南】  Python函数接口文档化_自动化说明【指导】  PythonFastAPI项目实战教程_API接口与异步处理实践  Win11麦克风没声音怎么设置_Win11麦克风权限及驱动修复【教程】  Win11怎么开启窗口对齐助手_Windows11系统多任务处理设置  WindowsUSB驱动安装异常怎么办_USB驱动重建与恢复教程  Windows怎样关闭Edge新标签页广告_Windows关闭Edge新标签页设置【步骤】  为什么Go建议使用error接口作为错误返回_Go Error接口设计原因说明  c++如何实现多态性_c++ 虚函数表原理与动态绑定机制【教程】  php串口通信波特率怎么选_根据硬件手册设置正确波特率【方法】  如何使用Golang构建简易投票统计功能_Golang投票数据汇总与展示示例  如何在 VS Code 中正确配置并使用 NumPy  如何在Golang中验证模块完整性_Golanggo.sum校验与安全实践  如何在Golang中实现邮件发送功能_Golang SMTP发送与错误处理示例  Windows电脑如何进入安全模式?(多种按键方法)  c++怎么实现大文件的分块读写_c++ 文件指针seekp与seekg偏移控制【方法】  Win10怎样清理C盘Steam游戏缓存_Win10清理Steam游戏缓存步骤【步骤】  Python技术债务管理_长期维护解析【教程】  Windows10如何更改系统字体大小_Win10辅助功能文本缩放设置  如何在Golang中实现WebSocket广播_使用Channel和协程分发消息  php命令行怎么运行_通过CLI模式执行PHP脚本的步骤【说明】  Win11怎么自动隐藏任务栏_Win11全屏显示设置【美化】  Python多线程使用规范_线程安全解析【教程】  如何使用Golang sync.Map实现并发安全map_避免锁竞争 

     2025-12-31

  • 了解您产品搜索量及市场趋势,制定营销计划

    同行竞争及网站分析保障您的广告效果

    点击免费数据支持

    提交您的需求,1小时内享受我们的专业解答。

    致胜网络推广营销网


    致胜网络推广营销网

    致胜网络推广营销网专注海外推广十年,是谷歌推广.Facebook广告全球合作伙伴,我们精英化的技术团队为企业提供谷歌海外推广+外贸网站建设+网站维护运营+Google SEO优化+社交营销为您提供一站式海外营销服务。

     915688610

     17370845950

     915688610@qq.com

    Notice

    We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
    You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.